Embedded Entity in EmbeddedId not persisted. Error 631 at select.

#1

hello developers,

what is wrong?

---

package debug;

import static java.lang.System.out;
import static javax.persistence.Persistence.createEntityManagerFactory;

import java.io.File;

import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.Id;

/**
 * @author Stanislav Jakuschev 27.02.2023
 * 
 *         case 1: Works not: if field AId.b is not @Embedded annotated.
 *
 *         case 2: Works: if field AId.b is @Embedded annotated.
 * 
 *         issue: In case 1 transaction is committed, but select fails!
 * 
 *         question: Is @Entity annotation of class B not sufficient enough, or
 *         am I completely wrong?
 */
public class OdbError631 {

    public static void main(String[] args) {

        String dbName = OdbError631.class.getSimpleName() + ".odb";

        new File(dbName).delete();
        new File(dbName + "$").delete();

        EntityManager em = createEntityManagerFactory(dbName).createEntityManager();

        em.getTransaction().begin();

        em.persist(new A(new AId(new B(1))));

        em.getTransaction().commit();

        em.clear();

        out.println(em.createQuery("select a from A a", A.class).getResultList());
    }

    @Entity
    public static class A {

        @EmbeddedId
        private AId id;

        public A() {
        }

        public A(AId id) {
            this.id = id;
        }

        @Override
        public String toString() {
            return "A [id=" + id + "]";
        }

    }

    @Entity
    public static class B {

        @Id
        public int id;

        public B() {
        }

        public B(int id) {
            this.id = id;
        }

        @Override
        public String toString() {
            return "B [id=" + id + "]";
        }

    }

    @Embeddable
    public static class AId {

        // @Embedded // case 1, not annotated, error 631
        @Embedded // case 2, annotated, all fine
        public B b;

        public AId() {
        }

        public AId(B b) {
            this.b = b;
        }

        @Override
        public String toString() {
            return "AId [b=" + b + "]";
        }

    }

}

---

19:05:31.423 [main] DEBUG org.jboss.logging - Logging Provider: org.jboss.logging.Log4j2LoggerProvider
19:05:31.463 [main] INFO org.hibernate.jpa.boot.internal.PersistenceXmlParser - HHH000318: Could not find any META-INF/persistence.xml file in the classpath
19:05:31.464 [main] DEBUG org.hibernate.jpa.HibernatePersistenceProvider - Located and parsed 0 persistence units; checking each
19:05:31.465 [main] DEBUG org.hibernate.jpa.HibernatePersistenceProvider - Found no matching persistence units
Exception in thread "main" [ObjectDB 2.8.8] javax.persistence.EntityNotFoundException
Entity is not found: debug.OdbError631$B#1 (error 631)
    at com.objectdb.jpa.JpaQuery.getResultList(JpaQuery.java:738)
    at debug.OdbError631.main(OdbError631.java:37)

---

thank you

 
#2

The problem with this program is that the B entity object is not persisted.

You can fix it by persisting the B object explicitly:

  em.getTransaction().begin();
  B b = new B(1);
  em.persist(b);
  em.persist(new A(new AId(b)));
  em.getTransaction().commit();

or by specifying CascadeType.PERSIST:

  @Embeddable
  public static class AId {
      @OneToOne(cascade = CascadeType.PERSIST)
      public B b;

Apparently the @Embedded annotation works as CascadeType.PERSIST, although B is an entity class, not embeddable class, so CascadeType.PERSIST is the right annotation to use.

ObjectDB Support

Reply