2
votes

I've been trying to do a simple one to many object binding in DataNucleus JDO. It's just two classes (i stripped a simple fields):

@PersistenceCapable(table="ORDER",schema="mgr")
public class Order {
    @PrimaryKey(column="id")
    @Persistent(valueStrategy=IdGeneratorStrategy.NATIVE,column="id")    
    private Long id;

    @Persistent(defaultFetchGroup="false",column="customer_id")
    @Element(column="customer_id")  
    private Customer customer;
}

And a class Customer having a list of orders

@PersistenceCapable(table="customer",schema="mgr",identityType=IdentityType.DATASTORE)
@DatastoreIdentity(strategy=IdGeneratorStrategy.NATIVE)
public class Customer {
    @PrimaryKey
    @Persistent(valueStrategy=IdGeneratorStrategy.NATIVE,column="id")    
    private Long id;

    @Persistent(mappedBy="customer") 
    private List<Order> orders;
}

The database table setup is extremely simple(a table for customer and a table for orders with a foreign key (customer_id) referencing customer). Yet, when i try to insert some orders for customer i receive an error

javax.jdo.JDODataStoreException: Insert of object "test.Order@17dd585" using statement "INSERT INTO ORDER (USER_COMMENT,ORDER_DATE,STATUS,CUSTOMER_ID,ORDERS_INTEGER_IDX) VALUES (?,?,?,?,?)" failed : Unknown column 'ORDERS_INTEGER_IDX' in 'field list'

Somehow DataNucleus is assuming, there is a column ORDERS_INTEGER_IDX (such column does not exist in the database). The only idea, that came to my mind is http://www.datanucleus.org/products/datanucleus/jdo/metadata_xml.html

In some situations DataNucleus will add a special datastore column to a join table so that collections can allow the storage of duplicate elements. This extension allows the specification of the column name to be used. This should be specified within the field at the collection end of the relationship. JDO2 doesnt allow a standard place for such a specification and so is an extension tag.

So cool! 'in some situations'. I have no idea how to make my situation not to be a subset of 'some situations' but I have no idea, how to get this working. Perhaps someone has allready met the "INTEGER_IDX" problem? Or (it is also highly possible) - im not binding the data correctly :/

1

1 Answers

3
votes

So you create the schema yourself. Your schema is inconsistent with metadata. You run persistence without validating your metadata against schema, and an exception results. DataNucleus provides you with SchemaTool to create or validate the schema against your metadata, so that would mean that you can detect the problem.

You're using an indexed list, so it needs an index for each element (or how else is it to know what position an element is in?). How can it assume there is an index? well it's a thing called the JDO spec (publically available), which defines indexed lists. If you don't want positions of elements storing then don't use a List (the Java util class for retaining the position of elements) ... so I'd suggest using a Set since that doesn't need position info (hence no index).

You also have a class marked as datastore identity, and then have a primary-key. That is a contradiction ... you have one or the other. The docs define all of that, as well as how to have a 1-N List relation ("JDO API" -> "Mapping" -> "Fields/Properties" -> "1-N Relations" -> "Lists" or "Sets")