Author/Work is the appropriate example. The Hibernate solution to this problem seems to be that, in a bi-directional many-to-many relationship, one side has to be "less equal" than the other. One side has more responsibility for managing the relation.
Add inverse = "true" to the Category side:
Code:
<class name="com.toot.toot.Category" table="Category">
...snip...
<set name="subscribers" lazy="false" inverse="true" cascade="none"
table="UserCategory" >
<key column="category_id"/>
<many-to-many class="com.toot.toot.User" column="user_id" />
</set>
</class>
and then
Code:
user.getCategories().add(category);
category.getSubscribers().add(user);
will not result in the duplicate relation being added to the UserCategory table.
This is because inverse="true" says that Category does
not have responsibility for creating the SQL that manages the relation. User does have that responsibility becuase inverse="false" is the default.
More about inverse is at
http://www.hibernate.org/155.html
Will