726 words

Issue #186 - JDO PersistenceManager.getSequence() returns null sometimes

BugVersion: 2.4.7Priority: NormalStatus: FixedReplies: 5
#1
2013-03-17 22:08

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.

spiffy
spiffy's picture
Joined on 2013-03-12
User Post #5
#2
2013-03-18 15:41

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
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,453
#3
2013-03-18 16:26

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?

spiffy
spiffy's picture
Joined on 2013-03-12
User Post #6
#4
2013-03-18 19:20

Sequences can be declared in classes using JDO annotations.

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

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,456
#5
2013-03-19 09:47

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.

spiffy
spiffy's picture
Joined on 2013-03-12
User Post #7
#6
2013-03-19 10:21

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
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #1,459

Post Reply

Please read carefully the posting instructions - before posting to the ObjectDB website.

  • You may have to disable pop up blocking in order to use the toolbar (e.g. in Chrome).
  • Use ctrl + right click to open the browser context menu in the editing area (e.g. for using a browser spell checker).
  • To insert formatted lines (e.g. Java code, stack trace) - select a style in the toolbar and then insert the text in the new created block.
  • Avoid overflow of published source code examples by breaking long lines.
  • You may mark in paragraph code words (e.g. class names) with the code style (can be applied by ctrl + D).
  • Long stack traces (> 50 lines) and complex source examples (> 100 lines) should be posted as attachments.
Attachments:
Maximum file size: 32 MB
Cancel