ObjectDB ObjectDB

LAZY @ManyToOne field functions as EAGER


In the code example below (also attached) I would like to understand why I am able to print to console a lazy @ManyToOne field after the entity manager closes. There is a switch DO_VIEW_BEFORE_CLOSE, and when it is true the fields are accessed and output before the finding entity manager closes and as expected both a LAZY @ManyToOne field and an EAGER @ManyToOne field are viewable:



But when I switch DO_VIEW_BEFORE_CLOSE to false, so that the fields are only accessed after the finding entity manager closes, I can still view b.cLazy, whereas I would expect b.cLazy to not be still resolved. [By constrast, using this approach an unmapped @OneToMany list is not still viewable, although a mapped @OneToMany list is, which I will discuss in another forum posting]

Q: Why is b.cLazy viewable after the finding entity manager closes, when it is marked as @ManyToOne(fetch=FetchType.LAZY) ?


package com.greensoft.objectdb.test.console;

import javax.persistence.*;

* @author Darren Kelly (Webel IT Australia)
public class TestLazyManyToOne {
     * If true the console view of the fields of the entities will be
     * called after find before the relevant EntityManager closes.
    final static boolean DO_VIEW_BEFORE_CLOSE = false;
     * @param args the command line arguments
    public static void main(String[] args) {
        String $connection = "objectdb:db/TestLazyManyToOne.tmp;drop";
        EntityManagerFactory emf =
        EntityManager  em = emf.createEntityManager();
        B b = new B("b");
        b.cLazy = new C("cLazy");
        b.cEager = new C("cEager");
        Long id = b.id;

        em = emf.createEntityManager();
        b = em.find(B.class, id);
        if (!DO_VIEW_BEFORE_CLOSE) em.close();
        //Output entities and fields

        if (DO_VIEW_BEFORE_CLOSE) em.close();
    abstract static public class A {
        Long id;

        String name;
        protected A(String name) {
            this.name = name;
        @Override public String toString() {
            return "{"+getClass().getSimpleName()+ "}"+ "["+id+"]\"" + name + "\"";

    static public class B extends A {
        public B(String name) {

        @ManyToOne(fetch=FetchType.LAZY, cascade= CascadeType.ALL)
        C cLazy;
        @ManyToOne(fetch=FetchType.EAGER, cascade= CascadeType.ALL)
        C cEager;              
    static public class C extends A {
        public C(String name) {




In JPA, LAZY (unlike EAGER) is merely a hint.

For example, ObjectDB always loads simple value fields eagerly (e.g. String fields), even if lazy loading is specified, since usually there is no benefit in lazy loading in these cases.

Regarding your example, ObjectDB can use lazy loading in OneToOne and ManyToOne relationships only in enhanced classes. If you run your test as recommended with enhancement enabled, e.g. 

java -javaagent:objectdb.jar com.greensoft.objectdb.test.console.TestLazyManyToOne

The output should be:


But when classes are not enhanced, ObjectDB has to ignore lazy loading and load "to-one" relationships eagerly, since  there is no way for ObjectDB to know that such relationships are expected to be accessed (there is no trigger), so such fields have to be loaded in advance.

ObjectDB Support

thanks for explanation, have tested and confirmed result.



To post on this website please sign in.