List of Enum Values in an entity

#1

Hello,

I'm new with ObjectDB and just tried out the example in the Eclipse/Glassfish tutorial (https://www.objectdb.com/tutorial/jpa/eclipse/ee).

After testing was successful, I extended the Guest Entity with an ArrayList of Enums:

private ArrayList<GuestFlag> flags;

The flags are stored into the database without any problem. In the explorer I can see that it is stored as array of Strings.

Unfortunately, when I try to load the flags from the database, the list is always null.

What am I doing wrong?

Joachim

#2

Arrays of enum values are expected to be supported by ObjectDB.

If the entity is enhanced, you may see a null value in the debugger before accessing the field, but when the field is accessed it is expected to be loaded automatically by ObjectDB (unless it is accessed by reflection).

Could you post a simple test case that shows the issue?

ObjectDB Support
#3

Hi,

the guest class is the only thing I changed in the whole application:

package .model.entity;


import java.io.Serializable;
import java.sql.Date;
import java.util.ArrayList;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.eummcr.datastore.model.GuestFlag;


/**
* Entity implementation class for Entity: Guest
*
*/
@Entity
public class Guest implements Serializable {

private static final long  serialVersionUID = 1L;

@Id
@GeneratedValue
Long       id;
private String     name;
private Date     signingDate;
private GuestFlag    status;
private ArrayList<GuestFlag> flags;


public Guest() {
}


public Guest(String name) {
  this.name = name;
  this.signingDate = new Date(System.currentTimeMillis());

  this.flags = new ArrayList<GuestFlag>();
  this.flags.add(GuestFlag.booked);
  this.flags.add(GuestFlag.registered);
}


@Override
public String toString() {

  System.out.println("Get String of Guest: " + name);
  String flagNumber = flags == null ? "null" : Integer.toString(flags.size());
  System.out.println("    Number of Flags: " + flagNumber);
  System.out.println("             Status: " + (status != null ? status.name() : "null"));

  String output = name + " (signed on " + signingDate + ")";
  if (flags != null && flags.size() > 0) {
   for (GuestFlag flag : flags) {
    output += ", [" + flag.name() + "]";
   }
  }

  return output;
}
}

And as I said, the flags are stored in the database, but not read.

The "toString" method always tells me that the flags are null.

Flashbaer

#4

It is unclear. Maybe you see null values for old Guest instances that have been persisted before adding the list of flags? What application server do you use? Can you upload the entire web application?

The following test tries to reproduce the problem in a console application:

import java.util.*;

import javax.persistence.*;


public class T1276 {

    public static void main(String[] args) {
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb:test.tmp;drop");
       
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        MyEntity entity = new MyEntity();
        entity.list = new ArrayList<MyEnum>();
        entity.list.add(MyEnum.V1);
        entity.list.add(MyEnum.V2);
        em.persist(entity);
        em.getTransaction().commit();
        em.close();
       
        em = emf.createEntityManager();
        Long id = entity.id;
        entity = em.find(MyEntity.class, id);
        System.out.println(entity);
        em.close();
       
        emf.close();
    }

    @Entity
    public static class MyEntity {
        @Id @GeneratedValue Long id;
       
        ArrayList<MyEnum> list;
       
        @Override
        public String toString() {
            return "MyEntity#" + list;
        }
    }
   
    public static enum MyEnum {
        V1, V2, V3;
    }
}

but the output, as expected, is:

MyEntity#[V1, V2]
ObjectDB Support
#5

Hello,

I deleted the database a few times, so there are no Guests from before I added the list of Enums.

I use a Glassfish Server 4.0. 

Flashbaer

#6

We could reproduce the issue in the GuestBook web application.

The problem is that by default, collections are loaded lazily. Guest's toString is invoked in this tutorial on detached Guest instances, and in detached objects only fields that have been loaded before detachment (e.g. defined as eager rather than lazy, or accessed) are available.

One way to solve the problem is to change the fetch policy of the field from LAZY to EAGER:

    private @OneToMany(fetch=FetchType.EAGER) List<GuestFlag> flags;

According to our checks this solves the problem, and produces the expected output:

1. aaa (signed on 2013-11-20), [booked], [registered]
2. bbb (signed on 2013-11-20), [booked], [registered]
ObjectDB Support
#7

Great, it works!

However, my Eclipse tells me that

Target entity "datastore.model.GuestFlag" is not an Entity

Do you know if this is an error of Eclipse or is this just a ObjectDB specific case that the @OneToMany works here?

Thank you

Flashbaer

#8

Eclipse is right.

It shouldn't make a difference for ObjectDB, but to remove this error / warning try:

private @Basic(fetch=FetchType.EAGER) List<GuestFlag> flags;
ObjectDB Support

Reply