Home » Support » Forum » Unable to persist TreeMap

Unable to persist TreeMap

#1
import java.util.SortedMap;
import java.util.TreeMap;
import javax.persistence.Entity;
//----------------
@Entity
class Person {
public SortedMap<String, String> memberships = new TreeMap<String, String>();
} //Person

 

import javax.jdo.PersistenceManager;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.LockModeType;
import javax.persistence.Persistence;
//----------------
@Entity
public class Test {
    //----------------
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
          "objectdb:D:\\eclipse\\workspace\\TestProject\\Storage.odb");
        EntityManager em = emf.createEntityManager();
        Person p = new Person();
        p.memberships.put("Bar Association", "President");
        em.getTransaction().begin();
        em.persist(p);
        em.getTransaction().commit();
        System.out.println("Created memberships: " + p.memberships);
        emf.close();
        //-------
        emf = Persistence.createEntityManagerFactory(
          "objectdb:D:\\eclipse\\workspace\\TestProject\\Storage.odb");
        em = emf.createEntityManager();
        p = em.find(Person.class, 1);
        System.out.println("Retrieved memberships: " + p.memberships);
        emf.close();
    } //main
//----------------
} //Test

Produces console output:

Created memberships: {Bar Association=President}
Retrieved memberships: {}





#2

Just tried and the output is as expected:

Created memberships: {Bar Association=President}
Retrieved memberships: {Bar Association=President}

Maybe you have an existing database in that path, which contains a Person#1 instance with an empty map?

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#3

My version of the test now runs correctly also, after I deleted the database and reran it causing a new database to be created. Maybe my first test was retrieving an old Person that I didn't realized existed. I neglected to check first. Hopefully this additional information will help find the problem in the real application. I'll post what the original problem was when I find it.

Your help and quick response was much appreciated.

#4

Application still not working:

[ObjectDB 2.5.0 Enhancer]
1 persistable type has been enhanced:
    Association

[ObjectDB 2.5.0 Enhancer]
1 persistable type has been enhanced:
    Person

Created key: Bar Association value: President
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:31)
at Enhance.main(Enhance.java:6)

import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
//=======================================
public class Test {
//----------------
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(
  "objectdb:D:\\eclipse\\workspace\\TestProject\\Storage.odb");
EntityManager em = emf.createEntityManager();
Person pc = new Person();
Association association = new Association("Bar Association");
pc.memberships.put(association, "President");
for(Map.Entry<Joinable, String> entry :
  pc.memberships.entrySet()) {
    System.out.println("Created key: " + entry.getKey() +
      " value: " + entry.getValue());
} //for
em.getTransaction().begin();
em.persist(association);
em.persist(pc);
em.getTransaction().commit();
emf.close();
//-------
emf = Persistence.createEntityManagerFactory(
  "objectdb:D:\\eclipse\\workspace\\TestProject\\Storage.odb");
em = emf.createEntityManager();
Person pr = em.find(Person.class, 1);
for(Map.Entry<Joinable, String> entry :
  pr.memberships.entrySet()) {
    System.out.println("Retrieved key: " +
      entry.getKey() + " value: " + entry.getValue());
} //for
emf.close();
} //main
//----------------
} //Test

import java.util.SortedMap;
import java.util.TreeMap;
import javax.persistence.Entity;
//=======================================
@Entity
class Person {
public SortedMap<Joinable, String> memberships =
  new TreeMap<Joinable, String>();
//----------------
} //Person

import javax.persistence.Entity;
//=======================================
@Entity
public class Association implements Joinable {
public String name;
//---------------------------
public Association(String name) {
this.name = name;
} //Association
//---------------------------
@Override
public int compareTo(Joinable j) {
return toString().compareTo(j.toString());
} //compareTo
//---------------------------
@Override
public String toString() {
return name;
} //toString
} //Association
//=======================================
@Entity
public interface Joinable extends Comparable<Joinable>{
} //Joinable

 





 

#5

If you open the database in the Explorer you will see that now the Id of the Person instance is #2. Id #1 is now allocated to the Association instance. Accordingly, the find should return null.

When something doesn't work, try to check the reasons in the debugger, the Explorer, etc. If the reason is still unknown, please post to the forum and we will be happy to help.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#6

It has been the ObjectDB Explorer that I've primarily been looking at, and where there might be a bug.

Making the below correction (as you pointed out) to the above test (sorry for the mistake):

    Person pr = em.find(Person.class, 2);

Still shows the MapEnty in Explorer with an incorrect Value:

Key Association#1 {R} {}
Value Unknown  null

 

application/vnd.openxmlformats-officedocument.wordprocessingml.document iconMapValueNull.docx (39.2KB)
Explorer screen shot showing incorrect null for MapEntry Value
#7

There is indeed a problem is viewing the TreeMap in the Explorer.

The reason for this is that the Explorer generates synthetic classes instead of your classes, and the generated classes do not include an appropriate implementation of compareTo, which is essential in order to process a TreeMap properly.

We will check what can be done to fix this problem. Thank you for this report.

Meanwhile, as a workaround, run the Explorer with your classes available in the classpath.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#8

Build 2.5.1_02 should fix most cases.

Adding the classes to the Explorer classpath may still be needed in some cases.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)

Post Reply

To post a reply and/or subscribe to update notifications - please login