Duplicate the collection of objects and save to Hibernate / JPA

I want to duplicate a collection of objects in my database. I am returning the collection with:

CategoryHistory chNew = new CategoryHistory(); CategoryHistory chLast = (CategoryHistory)em.createQuery("SELECT ch from CategoryHistory ch WHERE ch.date = MAX(date)").getSingleResult; List<Category> categories = chLast.getCategories(); chNew.addCategories(categories)// Should be a copy of the categories: OneToMany 

Now I want to duplicate the list of "categories" and save it using EntityManager. I am using JPA / Hibernate. UPDATE

Having learned how to separate my entities, I need to know what to separate: current code:

  CategoryHistory chLast = (CategoryHistory)em.createQuery("SELECT ch from CategoryHistory ch WHERE ch.date=(SELECT MAX(date) from CategoryHistory)").getSingleResult(); Set<Category> categories =chLast.getCategories(); //detach org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession(); session.evict(chLast);//detaches also its child-entities? //set the realations chNew.setCategories(categories); for (Category category : categories) { category.setCategoryHistory(chNew); } //set now create date chNew.setDate(Calendar.getInstance().getTime()); //persist em.persist(chNew); 

This throws an exception failed to lazily initialize a collection of role: entities.CategoryHistory.categories, no session or session was closed .

I think he wants to be lazy to upload categories again, since I am removing them. What should I do now?

+4
source share
4 answers

Aaron Diguila answer - the way here, i.e. you need to detach your instances, set the business key to null , and then persist them.

Unfortunately, there is no way to disconnect one object from the entity manager with JPA 1.x (JPA 2.0 will have EntityManager.detach(Object) and fix it). So, either wait for JPA 2.x (not the option I'm assuming) or use the Hibernate underlying Session .

To do this, you can pass the EntityManager delegate to the Hibernate session.

 Session session = (Session) em.getDelegate(); 

Of course, this only works if you use Hibernate as your Java Persistence provider, because the delegate is the Session API.

Then, to detach your object:

 session.evict(object); 

UPDATE: According to Be careful when using EntityManager.getDelegate () , when using GlassFish you must use (and probably in your case too):

 org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession(); 

But in JBoss would work not to propose to use the said code previously.

 org.hibernate.Session session = (Session) em.getDelegate(); 

Although I understand that using getDelegate() makes JPA code not portable, I have to admit that I did not expect the result of this method call to be implementation specific.

UPDATE2: In order to answer the updated part of the question, I am not sure that you were looking forward to the categories. This is not the best way to do this, but what happens if you call categories.get(0) before the eviction? In addition, I may miss this part, but where do you collapse the key from the categories?

+6
source

You need to separate your instances from the session. There are three ways to do this:

  • Close the session (perhaps this is not possible in your case).
  • Serialize the object and deserialize it again.
  • Cloning an object and clearing / zeroing the primary key / identifier field.

Then you must change the business key (so that new instances will return false when calling equals() with an unmodified instance). This is an important step: without it, Hibernate will again bind instances to existing ones in the database, or you will get other strange errors.

After that, you can save new copies in the same way as any other copy.

+8
source

Good,

Since I use Glassfish v3, and JPA2.0 is final, I used EntityManager.detach () Strange ejb3-persistence.jar was included in my library, so I threw it away and used javax.persistence glass jar. The detach method exists, but my version of sleep mode is not yet implemented

0
source
  • Clone or copy the properties of each object. You can use Apache BeanUtils.copyProperties(copy, orig)
  • In OpenJPA, manually remove object monitoring using Apache BeanUtils:

    BeanUtils.setProperty(copy, "pcVersionInit", false);

  • Set the default primary key to / null.

  • Keep every copy.

Also see: http://www.java-tutorial.ch/java-persistence-api/how-to-persist-duplicate-of-an-entity-with-openjpa

0
source

All Articles