Home > Blockchain >  Why does bidirectional @OneToMany work without second save()
Why does bidirectional @OneToMany work without second save()

Time:04-05

According to this fabulous article by Thorben Janssen a bidirectional association for @OneToMany works like this:

Item item3 = new Item();
item3.setName("Third Item");
item3.setOrder(order);
em.persist(item3);
 
order = em.find(PurchaseOrder.class, orderId);
order.getItems().add(item3);

In other words,

  1. Persist the owner of the @ManyToOne relationship
  2. Just add the owner to the @OneToMany entity, you don't even need to call save() a second time

Now, why is that? I implemented this and played around with some tests just to get this right. For me personally, this is highly obfuscated hibernate magic and this behavior does not make sense.

This is why I want to dive deeper into how Hibernate works so I'm trying to understand what exactly is happening here. I know the entities are tied to the hibernate persistence layer but from here on my knowledge gets a bit wonky.

CodePudding user response:

To understand what's going on you need to be familiar with Hibernate ORM entity states.

In your case, both entities are managed and therefore Hibernate ORM knows that it needs to apply the changes. item3 is managed because it has been persisted, order is managed because it's the result of a find.

The javadoc for session.save starts with:

Persist the given transient instance ...

None of the entities are transient in this case.

Note that you would be able to change the example, depending on how you map the association with different cascade types.

For example, if the association items is mapped using CascadeType.PERSIST, this would also work:

Order order = new Order();

Item item3 = new Item();
item3.setName("Third Item");

item3.setOrder(order);
order.getItems().add(item3);

em.persist(order);
  • Related