Tuesday, July 15, 2008

Hibernate annotations: Reversing the bidirectional relationship

written by Marcel Panse

Making a bidirectional relationship in hibernate using annotations is easy. Just make a ManyToOne at one side and a OneToMany at the other. Use the mappedBy property to make the relationship bidirectional.
I thought this means when editing the Collection side and saving this collection side, that hibernate would update the foreign key automatically at the other table.

For example, when you have a User with multiple Products and you add a product to the user like user.products.addItem(product). And then saves the user like userDao.save(user). This does not update the foreign key in the product table. And next time when you retrieve the user.products from the database, the collection will be empty again. The same goes when you remove a product from the collection.

It all works fine when you do something like product.user = user; and save the product. Then when you retrieve the user the product collection will hold the added product.

The solution is to add a JoinColumn annotation to BOTH sides.

Here is an example:

@OneToMany(targetEntity=ProductImpl.class, cascade={CascadeType.ALL})
@JoinColumn(name = "product_id")
private Collection products;

@ManyToOne(targetEntity=UserImpl.class, cascade={CascadeType.ALL})
@JoinColumn(name = "user_id")
private User user;


kaefert said...

I have exactly the problem your describing here. However, I don't understand your solution exactly.

What tables hold the columns "product_id" & "user_id" that you reference in the JoinColumn Annotation?

Anonymous said...

Great stuff, but it would be easier if you showed noth classes. Its a bit hard to know exactly where you placed your code.