On initialisation of lists: impact on migration from EclipseLink to ObjectDB

#1

I would like to draw the attention of those assessing migration from EclipseLink ORM to ObjectDB to a significant difference in the initialization of persistent lists, namely that EclipseLink injects a List implementation into the List field to be initialise it during EntityManager.persist().

So in EclipseLink the following works:

public class HasListOfBlocks {
..
    private List<Block> blocks; 
        //EclipseLink: no need to init, will be done by EntityManager.persist()
    @OneToMany(cascade=CascadeType.ALL)
    public List<Block> getBlocks() {
        return blocks;
    }
    public void setBlocks(List<Block> blocks) {
        this.blocks = blocks;
    }
    public boolean addBlock(Block b) {
        return getBlocks().add(b);//CAUTION: assumes list inited
    }
}

Then used as:

@PersistenceContext private EntityManager em;
..
    HasListOfBlocks h = new HasListOfBlocks();
    em.persist(h);
    em.flush(h);//optional
    Block childBlock  = new Block();
    em.persist(childBlock);
    h.addBlock(); //assumes List now inited

Whereas in ObjectDB the above would lead to a NullPointerException on using the list, one must therefore defensively ensure that the list is initialised:

public class HasListOfBlocks {
..
    private List<Block> blocks = new ArrayList<Block>();
    @OneToMany
    public List<Block> getBlocks() {
        return blocks;
    }
    public void setBlocks(List<Block> blocks) {
        this.blocks = blocks;
    }
    public boolean addBlock(Block b) {
        return getBlocks().add(b);
    }
}

This has impact on migration; in my case I would have to find an explicitly init about 1000 lists, because I have a large number of hand-coded (harder to find) and generated (easy to regenerate) Lists in entities.

There are cases where one should explicitly init such a @OneToMany list anyway, namely when an entity is "self-constructing" or "self-wiring", i.e. it creates some child elements and adds them to its own Lists, and then relies on cacade to persist the children, which will be persisted with the parent. So in that case, using the example above, addBlock would be needed before EntityManager.persist is called, and one can't rely on a JPA provider to initialise the List.

I am not sure whether there is a configuration switch to change this List init behaviour in ObjectDB, but the default behaviour is clearly different from EclipseLink, and so has an impact on migration.

I have previously examined the JavaEE, JPA, and EclipseLink documentation and examples and they have examples of Lists both explicitly initialised and of not initialised. There seems to be no best practice recommendation. The EclipseLink forums and many Java forums contains some quite heated debates on whether one should init an @OneToMany list or not. But in ObjectDB it seems one has to.

Hoping this helps somebody,

Webel

#2

Thank you for this useful information.

It might be a good idea to support different policies (using configuration) in future ObjectDB versions.

ObjectDB Support

Reply