614 words

Issue with orphanRemoval and multiple EntityManagers

#1
2012-04-04 12:17

Hi,

We have a problem where our database size grows over time more than expected. We've traced it down to the following issue:

I have some entities that are using OneToMany relationship with orphanRemoval set to true. I use a new EntityManager for each transaction (which normally happens in multithreaded application). When I create a child entity in one transaction and then remove it in another transaction, the database still contains 1 child entity. If I remove it and add another child entity, the database contains 3 child entities. If I use the same EntityManager for both transactions for these scenarios, the database contains 0 and 2 child entities respectively.

The expected result is 0 and 1 respectively, regardless of which entity manager is used.

The test case attached, I was using version 2.3.7_08.

Kind regards,

Natalia.

natmaclin
natmaclin's picture
Joined on 2011-11-04
User Post #25
#2
2012-04-04 19:48

Thank you for this report and for the test. Here is the same test in one class format and after omission of irrelevant elements (please use this format in your posts when possible):

import java.util.*;
 
import javax.persistence.*;
 
 
public class F386 {
 
    public static void main(String [] args){
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb:test.tmp;drop");
        long orgId = 0;
 
        Organisation newOrganisation = new Organisation();
        newOrganisation.addElectronicAddress(
            new ElectronicAddress("natalia.levine@contextspace.com"));
 
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();               
        em.persist(newOrganisation);
        em.getTransaction().commit();
        orgId = newOrganisation.getId();
        em.close();
 
        em = emf.createEntityManager();
        Organisation originalOrganisation =
            em.find(Organisation.class, orgId);      
        originalOrganisation.getElectronicAddresses().clear();       
        originalOrganisation.addElectronicAddress(
            new ElectronicAddress("natalia@contextspace.com"));
        em.getTransaction().begin();
        //em.merge(originalOrganisation);
        em.getTransaction().commit();
 
        TypedQuery<ElectronicAddress> q3 = em.createQuery(
            "select t from " + ElectronicAddress.class.getName() + " t",
            ElectronicAddress.class);
        List<ElectronicAddress> res3 = q3.getResultList();
 
        System.out.println("Number of addresses: "+res3.size());
        em.close();
 
        emf.close();
    }
 
    @Entity
    public static class Organisation {
 
        @Id
        private long id;
 
        @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval=true)
        private List<ElectronicAddress> electronicAddresses =
            new ArrayList<ElectronicAddress>();
 
        public Organisation() {
            super();
        }
 
        public long getId() {
            return id;
        }
 
        public List<ElectronicAddress> getElectronicAddresses() {
            return electronicAddresses;
        }
 
        public void addElectronicAddress(ElectronicAddress electronicAddress) {
            electronicAddresses.add(electronicAddress);
        }
    }
 
    @Entity
    public static class ElectronicAddress  {
 
        private String address;
 
        public ElectronicAddress() {
        }
 
        public ElectronicAddress(String address) {
            this.address = address;
        }
    }
}

Your test demonstrated 2 issues:

  • Duplication of new objects during cascading merge - this is a known issue. You may subscribe to it, and until it is solved use workarounds (i.e. avoiding cascading merge to new objects). Actually in this test merge is not really needed so removing the merge solves the problem.
  • Detecting orphan objects in reflection mode. This is fixed now in build 2.3.7_13. Notice that the test works well also with previous builds when enhancement is used. So even though it is good that you reported the bug and it is now fixed, you should also verify that your application uses enhanced classes (which are much more efficient).
ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #997
#3
2012-04-05 00:17

This test case has been distilled from very large amount of code, some of it not under our control. Refactoring all that code to remove cascading merge is not possible. When are you planning to fix the underlying issue?

Regarding using enhanced classes - we did try to use them, but it had it's own set of issues, so we moved back to plain version. Are you saying that you do not support using your DB without enchanced classes?

Regards,

Natalia.

natmaclin
natmaclin's picture
Joined on 2011-11-04
User Post #26
#4
2012-04-05 10:32

> When are you planning to fix the underlying issue?

Usually bugs are fixed immediately when found. This is one of a very few bugs that require more time to be fixed. It is unknown yet when it will be fixed but your subscription to it now may accelerate it.

> Are you saying that you do not support using your DB without enchanced classes?

No, it is supported of course. But since the 2 modes use separate code in many areas (e.g. detecting orphan entities) bugs are not identical. However, enhanced classes are much more efficient in performance and in memory consumption, so it is highly recommended to use only enhanced classes in production.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #999
#5
2012-04-21 19:22

Build 2.3.7_18 fixes the cascading merge issue.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,029

Post Reply

Please read carefully the posting instructions - before posting to the ObjectDB website.

  • You may have to disable pop up blocking in order to use the toolbar (e.g. in Chrome).
  • Use ctrl + right click to open the browser context menu in the editing area (e.g. for using a browser spell checker).
  • To insert formatted lines (e.g. Java code, stack trace) - select a style in the toolbar and then insert the text in the new created block.
  • Avoid overflow of published source code examples by breaking long lines.
  • You may mark in paragraph code words (e.g. class names) with the code style (can be applied by ctrl + D).
  • Long stack traces (> 50 lines) and complex source examples (> 100 lines) should be posted as attachments.
Attachments:
Maximum file size: 32 MB
Cancel