ObjectDB ObjectDB

Issue #1074: JDO PersistenceManager.getSequence() returns null sometimes

Type: Bug ReoprtVersion: 2.4.7Priority: NormalStatus: FixedReplies: 5
#1

When using JDO without annotations, database sequences are normally defined in the ORM file. Following discussion on the forum I was told that ObjectDB supports sequences if specified in the JDO file. Unfortunately, it doesn't seem to be supported consistently. It appears to work only in the situation that a new odb file has just been created AND something has been persisted to it. If nothing has yet been persisted, or if the odb file is not newly created, getSequence() returns null.

Code to reproduce:

import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.datastore.Sequence;
import testcase.Thing;

public class Testcase {

    public static void main(String[] args) {
        PersistenceManagerFactory factory = new com.objectdb.jdo.PMF();
        factory.setConnectionURL("build/testcase.odb");
        PersistenceManager pm = factory.getPersistenceManager();

        Sequence seq1 = pm.getSequence("seq"); // per JDO spec, it should be testcase.seq
        if (seq1 == null)
            System.out.println("getSequence 1 returned null"); // it should never be null

        pm.currentTransaction().begin();
        Thing thing = new Thing("hello");
        pm.makePersistent(thing);
        pm.currentTransaction().commit();

        Sequence seq2 = pm.getSequence("seq");
        long next = seq2.nextValue(); // this works with a clean database but not an existing database
        System.out.println("sequence nextValue = " + next);

        pm.close();
        factory.close();
    }
}

Run it twice, and it will run to completion the first time but bomb out with NullPointerException the second time.

Entity class, in package testcase:

package testcase;

public class Thing {
    private String message;
    public Thing(String mess) {
        message = mess;
    }
}

package.jdo (in the root package; you can verify that it is being read at run-time by introducing an error such as an invalid sequence strategy):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jdo PUBLIC "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN" "http://java.sun.com/dtd/jdo_2_0.dtd">
<jdo>
  <package name="testcase">
    <class name="Thing" identity-type="datastore"/>
    <sequence name="seq" factory-class="java.lang.Long" strategy="contiguous" />
  </package>
</jdo>

An additional minor issue is that ObjectDB appears to ignore the package name when the sequence is defined inside a package, but we can live with that, since changing that doesn't require changing our large existing JDO 1.2 codebase.

edit
delete
#2

Build 2.4.7_04 fixes this problem.

Regarding the sequence names, the JDO specification is not completely clear.

Do you expect the sequence in the example to be named "testcase.seq"?

What about sequences that are declared in classes, should they use the package name? Maybe also the class name?

This could be easily fixed if this is how it works in other JDO implementations.

ObjectDB Support
edit
delete
#3

Confirmed that 2.4.7_04 fixes the problem - thanks!

Yes, I expect the sequence to be named "testcase.seq", the full package name being used to prefix sequence name to avoid name clashes between different packages. This is how all the other JDO implementations I've used (Xcalia, Versant, Datanucleus and Kodo) behave.

I'm not sure what you mean by sequences declared in classes - if you mean factory classes, then yes, it's normal to get the sequence name using the full package and class name of the factory class. Or is there another way of declaring sequences in classes that I haven't come across?

edit
delete
#4

Sequences can be declared in classes using JDO annotations.

Please try build 2.4.7_05 that should fix the naming issue.

ObjectDB Support
edit
delete
#5

I haven't used the JDO Sequence annotation myself, but I believe it's a class-level annotation so referring to the sequence with the fully qualified class name sounds right to me.

Using 2.4.7_05, both nextValue() and currentValue() work as expected - thanks! That will certainly help us port our code to ObjectDB.

edit
delete
#6

Sequences are defined using class annotations because annotations cannot be assigned to packages, but usually annotations should behave similarly to the XML metadata. Therefore, the name of a sequence that is defined by an annotation, is now based also on the package name (of the class) and not on the class name. Unfortunately the JDO spec does not specify how exactly it should work. 

Thank you for this report.

ObjectDB Support
edit
delete

Reply

To post on this website please sign in.