views:

8

answers:

0

Hi all,

I have an object (User) which has none or many Tags. Any User can have any number of Tags, so there's a join table, user_tags which has a user_id and tag_id field.

In User.hbm.xml, this is mapped as:

    <set name="Tags" table="user_tags">
        <key column="user_id"/>
        <many-to-many column="tag_id"
            unique="true"
            class="Tag"/>
    </set>

due to the Hibernate docs stating:

A unidirectional one-to-many association on a join table is the preferred option. Specifying unique="true", changes the multiplicity from many-to-many to one-to-many.

Now, I've added a uniqueness on user_id and tag_id in user_tags as this is a relationship that's often queried.

Upon adding of another Entity, also with tags, the new Entity's tags are merged with the Users tags like this:

boolean found = false;
for ( Tag t : entityTags ) {
    found =  false;

    for ( Tag u : userTags ) {
        if ( u.getTag() == t.getTag() ) {
            found = true;
            break;
        }
    }

    if ( found ) {
        break;
    }

    userTags.add( t );
}

user.setTags( userTags );
user.save();

This loop's a bit clumsy, but it's trying to prove a point.

The ConstraintViolationException is thrown when user.save() is called. This is an inherited method that calls session.saveOrUpdate() to save itself.

All Tags added in the loop already exist in the tags table in the database, but it seems that Hibernate can't keep track of the relationships that exist in the user_tags table, so simply tries to insert them all again.

Is there a best-practice way of handling these types of relationships? Is my mapping file wrong?

related questions