ObjectDB ObjectDB

Issue #595: New entity objects are duplicated on merge cascading

Type: Bug ReoprtVersion: 2.3.4Priority: HighStatus: FixedReplies: 3
#1

When merge is cascaded to a new entity object that has not been persisted yet - it becomes persisted twice rather than once.

This was demonstrated by a Java EE application in this forum thread but may be reproduced also in a simple console test case:

import java.util.*;

import javax.persistence.*;


@Entity
public class T595 {
    public static void main(String[] args) {
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb:$objectdb/db/test.tmp;drop");
       
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        em.persist(new Book());
        em.getTransaction().commit();
        em.close();
       
        em = emf.createEntityManager();
        Book book = em.find(Book.class, 1);
        em.close();
       
        em = emf.createEntityManager();
        em.getTransaction().begin();
        book.chapters = Arrays.asList(new Chapter());
        em.merge(book);
        em.getTransaction().commit();
        em.close();
       
        em = emf.createEntityManager();
        Query query = em.createQuery("SELECT COUNT(c) FROM Chapter c");
        System.out.println(query.getSingleResult());
        em.close();

        emf.close();
    }
   
    @Entity
    public static class Book {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
       
        @OneToMany(cascade= CascadeType.ALL, fetch= FetchType.EAGER)
        private List<Chapter> chapters;
    }

    @Entity
    public static class Chapter {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    }       
}

 

 

ObjectDB Support
edit
delete
#2

Fixing this bug may require totally new implementation of merge operations.

So unfortunately an immediate fix is not possible.

But this issue has a high priority and hopefully will be fixed soon.

ObjectDB Support
edit
delete
#3

This bug can also cause an "Attempt to persist a reference to a non managed ..." exception, when the duplicated object is referenced from another new / dirty entity object by a reference with cascading persist disabled.

The following test case demonstrates the exception:

import javax.persistence.*;


public class S246 {

    public static void main(String[] args) {

        String $connection = "objectdb:db/test.tmp;drop";
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory($connection);
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();
        em.persist(new A());
        em.getTransaction().commit();
       
        em.close();
        em = emf.createEntityManager();

        A a = em.find(A.class, 1L);
        B b = new B();
        a.b = b;
        b.owner = a;
        C c = new C();
        b.c = c;
        c.owner = b;

        em.getTransaction().begin();
        em.merge(a);
        em.getTransaction().commit();

        em.close();
        emf.close();
    }

    @Entity
    public static class A {
        @Id @GeneratedValue long id;

        @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        B b;
    }

    @Entity
    public static class B {
        @Id @GeneratedValue long id;

        @ManyToOne(fetch= FetchType.LAZY)
        A owner;
       
        @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        C c;
    }

    @Entity
    public static class C {
        @Id @GeneratedValue long id;

        @ManyToOne(fetch= FetchType.LAZY)
        B owner;
    }
}
ObjectDB Support
edit
delete
#4

This issue is fixed now in build 2.3.7_18.

ObjectDB Support
edit
delete

Reply

To post on this website please sign in.