Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate: OneToMany save children by cascade

In the class Parent there is a list List. When the parent is saved the children which have been added or changed shall be save / updated by hibernate.

I've found many explanations on this, however, I just don't get it to work.

Parent.class try A

@Entity public class Parent { // id and other attributes @OneToMany(mappedBy = "parent") @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.ALL) protected List<child> children; 

Parent.class try B

@Entity public class Parent { // id and other attributes   @OneToMany(mappedBy = "parent", cascade = { javax.persistence.CascadeType.ALL },  orphanRemoval = true)  @org.hibernate.annotations.Cascade({   org.hibernate.annotations.CascadeType.PERSIST,  org.hibernate.annotations.CascadeType.MERGE,  org.hibernate.annotations.CascadeType.REFRESH,  org.hibernate.annotations.CascadeType.SAVE_UPDATE,  org.hibernate.annotations.CascadeType.REPLICATE,  org.hibernate.annotations.CascadeType.LOCK,  org.hibernate.annotations.CascadeType.DETACH }) protected List<child> children; 

children are added to a new parent. Afterwards both are saved by

sessionFactory.getCurrentSession().saveOrUpdate(parent); 

when flushing, though, I get the following error:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: de.pockettaxi.backend.model.ride.RideSingle at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243) at org.hibernate.type.EntityType.getIdentifier(EntityType.java:456) at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:265) at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:275) at org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:295) at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3378) at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:520) at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:230) at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:154) at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219) at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) 

Does anybody see my mistake?

Thank you a lot!!

like image 963
Steve Eastwood Avatar asked Mar 10 '12 21:03

Steve Eastwood


People also ask

What is Cascade in OneToMany?

The meaning of CascadeType. ALL is that the persistence will propagate (cascade) all EntityManager operations ( PERSIST, REMOVE, REFRESH, MERGE, DETACH ) to the relating entities. It seems in your case to be a bad idea, as removing an Address would lead to removing the related User .

What is Cascade in Hibernate annotation?

Cascade is a convenient feature to save the lines of code needed to manage the state of the other side manually. The “Cascade” keyword is often appear on the collection mapping to manage the state of the collection automatically.

What is Cascade in Hibernate in which scenario we use it?

Cascading is about persistence actions involving one object propagating to other objects via an association. Cascading can apply to a variety of Hibernate actions, and it is typically transitive.


1 Answers

I guess if you answer the question from the first comment, we will come to this situation:

  • you have an already persisted parent
  • you have new child objects, that were not yet persisted
  • you add the children to the parent and do saveOrUpdate

In that case hibernate just cascades the save or update to the children, but they cannot be saved or updated as they have not been persistent yet. And now Hibernate says simply "I cannot update a non persistent entity"

In one sentence: Hibernate only cascades what it is issued to cascade. In this case you issue a "SAVE_UPDATE", which is cascaded then further to the children. I guess you expected Hibernate to be smart and switch to persist for the children here. But this is not how Hibernate works here, I came across similar situations before, too. A bit confusing, but if you once got how cascading works, you will see such situations.

like image 64
Markus Avatar answered Nov 11 '22 08:11

Markus