Issue #618: Eager Fetch of Map with Entities as Keys

Type: Bug ReoprtVersion: 2.3.4Priority: NormalStatus: ActiveReplies: 0
#1

Loading eagerly a map that uses entity objects as keys is currently unsupported, if the equals and hashCode methods of the keys are based on the key entity persistent content, since that content is unavailable during instantiation of the map.

The following test case demonstrates the problem:

import java.util.*;
import javax.persistence.*;


public class T618 {

    public static void main(String[] args) {

        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb:$objectdb/test.tmp;drop");

        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        MyEntity entity = new MyEntity();
        MyKeyEntity key = new MyKeyEntity("key");
        em.persist(key);
        entity.map.put(key, "value");
        em.persist(entity);
        em.getTransaction().commit();
        em.close();

        em = emf.createEntityManager();
        entity = em.find(MyEntity.class, 1);
        em.close();

        emf.close();
    }

    @Entity
    public static class MyEntity {
        @Id private long id = 1;
        @OneToMany(fetch=FetchType.EAGER)
        Map map = new HashMap();
    }
   
    @Entity
    public static class MyKeyEntity {
        private String name;
        MyKeyEntity(String name) {
            this.name = name;
        }
        @Override
        public boolean equals(Object obj) {
            return name.equals(((MyKeyEntity)obj).name);
        }
        @Override
        public int hashCode() {
            return name.hashCode();
        }
    }
}

Running the test results in a NullPointerException during map instantiation:

java.lang.NullPointerException
at T618$MyKeyEntity.hashCode(T618.java:51)
at java.util.HashMap.put(HashMap.java:372)
at objectdb.java.util.HashMap.put(Unknown Source)
at com.objectdb.o.MPT.I(MPT.java:299)
at com.objectdb.o.TYT.extractMap(TYT.java:59)
at com.objectdb.o.ENT.extractMap(ENT.java:1402)
at objectdb.java.util.HashMap.__odbBeforeAccess(Unknown Source)
at objectdb.java.util.HashMap.entrySet(Unknown Source)
at com.objectdb.o.MFT.a(MFT.java:92)
at com.objectdb.o.LDR.C(LDR.java:766)
at com.objectdb.o.LDR.F(LDR.java:911)
at com.objectdb.o.LDR.Vs(LDR.java:846)
at com.objectdb.o.FTP.d(FTP.java:109)
at com.objectdb.o.PFT.a(PFT.java:111)
at com.objectdb.o.LDR.C(LDR.java:795)
at com.objectdb.o.LDR.y(LDR.java:489)
at com.objectdb.o.LDR.x(LDR.java:448)
at com.objectdb.o.LDR.UU(LDR.java:669)
at com.objectdb.o.MST.aT(MST.java:522)
at com.objectdb.o.MST.aS(MST.java:454)
at com.objectdb.o.MST.U1(MST.java:427)
at com.objectdb.o.WRA.U1(WRA.java:248)
at com.objectdb.o.LDR.w(LDR.java:355)
at com.objectdb.o.LDR.v(LDR.java:293)
at com.objectdb.o.LDR.s(LDR.java:211)
at com.objectdb.o.OBC.aM(OBC.java:1058)
at com.objectdb.o.OBC.aK(OBC.java:971)
at com.objectdb.jpa.EMImpl.find(EMImpl.java:551)
at com.objectdb.jpa.EMImpl.find(EMImpl.java:474)
at T618.main(T618.java:26)

 

ObjectDB Support

Reply