4ntoine
4ntoine

Reputation: 20420

Autogenerated id using JPA for GAE (key as encoded String)

How to declare id field as "Key as encoded String" in JPA entity (not JDO) for usage in GAE Datastore? You can find example for JDO, but not for JPA.

Can't declare id fields as Long as entity is used in child-parent relations.

So, my entity is like this:

@Entity
public class EntityClass {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    private String id;

So, it uses both JPA and JDO annotations.

So, while trying to persist entity object i'm getting an exception:

Cannot have a null primary key field if the field is unencoded and of type String. Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long. org.datanucleus.store.appengine.FatalNucleusUserException: Invalid primary key for name.xxx.tips.db.User. Cannot have a null primary key field if the field is unencoded and of type String. Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long.

Full Stacktrace: Cannot have a null primary key field if the field is unencoded and of type String. Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long. org.datanucleus.store.appengine.FatalNucleusUserException: Invalid primary key for name.xxx.tips.db.User. Cannot have a null primary key field if the field is unencoded and of type String. Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long. at org.datanucleus.store.appengine.DatastoreFieldManager.storeStringPKField(DatastoreFieldManager.java:540) at org.datanucleus.store.appengine.DatastoreFieldManager.storeStringField(DatastoreFieldManager.java:460) at org.datanucleus.state.AbstractStateManager.providedStringField(AbstractStateManager.java:1023) at name.xxx.tips.db.User.jdoProvideField(User.java) at name.xxx.tips.db.User.jdoProvideFields(User.java) at org.datanucleus.state.JDOStateManagerImpl.provideFields(JDOStateManagerImpl.java:2715) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPreProcess(DatastorePersistenceHandler.java:357) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:267) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:256) at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3185) at org.datanucleus.state.JDOStateManagerImpl.flush(JDOStateManagerImpl.java:4513) at org.datanucleus.state.JDOStateManagerImpl.getExternalObjectId(JDOStateManagerImpl.java:1334) at org.datanucleus.state.JDOStateManagerImpl.getObjectId(JDOStateManagerImpl.java:1234) at name.xxx.tips.db.User.jdoGetObjectId(User.java) at org.datanucleus.jpa.JPAAdapter.getIdForObject(JPAAdapter.java:266) at org.datanucleus.ObjectManagerImpl.exists(ObjectManagerImpl.java:1953) at org.datanucleus.jpa.EntityManagerImpl.refresh(EntityManagerImpl.java:469)

Upvotes: 1

Views: 1389

Answers (2)

vargen_
vargen_

Reputation: 2790

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

import org.datanucleus.api.jpa.annotations.Extension;

@Entity
public class ChildEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    private String Id;

This works for me.

Upvotes: 1

DataNucleus
DataNucleus

Reputation: 15577

Why are you using JDO annotations if using JPA ? The annotation to use for extensions with JPA is

org.datanucleus.api.jpa.annotations.Extension

as shown here

Upvotes: 2

Related Questions