Google App Engine Datanucleus enhencer - PullRequest
       16

Google App Engine Datanucleus enhencer

1 голос
/ 18 января 2011

У меня следующий класс как суперкласс

@Entity
@MappedSuperclass
public class Location implements LocationCapable {

    @Basic
    private Double latitude;

    @Basic
    private Double longitude;

    @Basic
    private List<String> geocells;

    @PrePersist
    @Transient
    private void generateGeoCells() {
        geocells = GeocellManager.generateGeoCell(getLocation());
    }

    public Double getLongitude() {
        return longitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }

    public Double getLatitude() {
        return latitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    @Override
    @Transient
    @JsonIgnore
    public Point getLocation() {
        return new Point(latitude, longitude);
    }

    @Override
    @Transient
    @JsonIgnore
    public String getKeyString() {
        return latitude + ":" + longitude;
    }

    @Override
    public List<String> getGeocells() {
        return geocells;
    }

    public void setGeocells(List<String> geocells) {
        this.geocells = geocells;
    }

}

И еще один класс, который наследуется от этого

Но когда я пытаюсь запустить тест JUnit, я получаю этот

Caused by: org.datanucleus.metadata.InvalidMetaDataException: Class Location has application-identity and no objectid-class specified yet has 0 primary key fields. Unable to use SingleFieldIdentity.
at org.datanucleus.metadata.AbstractClassMetaData.determineObjectIdClass(AbstractClassMetaData.java:1032)
at org.datanucleus.metadata.ClassMetaData.populate(ClassMetaData.java:205)
at org.datanucleus.metadata.AbstractClassMetaData.validateSuperClass(AbstractClassMetaData.java:720)
at org.datanucleus.metadata.AbstractClassMetaData.determineSuperClassName(AbstractClassMetaData.java:642)
at org.datanucleus.metadata.ClassMetaData.populate(ClassMetaData.java:193)
at org.datanucleus.metadata.MetaDataManager$1.run(MetaDataManager.java:2317)
at java.security.AccessController.doPrivileged(Native Method)
at org.datanucleus.metadata.MetaDataManager.populateAbstractClassMetaData(MetaDataManager.java:2311)
at org.datanucleus.metadata.MetaDataManager.populateFileMetaData(MetaDataManager.java:2148)
at org.datanucleus.metadata.MetaDataManager.initialiseFileMetaDataForUse(MetaDataManager.java:864)
at org.datanucleus.metadata.MetaDataManager.loadPersistenceUnit(MetaDataManager.java:794)
at org.datanucleus.jpa.EntityManagerFactoryImpl.initialisePMF(EntityManagerFactoryImpl.java:488)
at org.datanucleus.jpa.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:355)
at org.datanucleus.store.appengine.jpa.DatastoreEntityManagerFactory.<init>(DatastoreEntityManagerFactory.java:63)
at org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider.createEntityManagerFactory(DatastorePersistenceProvider.java:35)
at javax.persistence.Persistence.createFactory(Persistence.java:172)
... 67 more

Также я попытался добавить в superclass ключевое поле, помеченное @Id, но это не дает результата для меня

Ответы [ 2 ]

2 голосов
/ 18 января 2011

У вас должно быть поле @Id, как говорится в сообщении.

0 голосов
/ 21 января 2011

Похоже, что это была какая-то проблема с расширением или затмением плагина, нет метра после перезапуска IDE, проблема исчезла.Но только эта проблема с ID.На самом деле я столкнулся с еще одной очень странной проблемой, связанной со встроенными объектами.У меня есть следующая модель домена:

@Entity
public class City {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key id;
    @Basic
    private String name;
    // Entity won't persist if location is not null, requires to persist with
    // further update
    @Embedded
    // @OneToOne(cascade = CascadeType.ALL) it works the same when I add or remove this line
    private Location location;

    /* getters and setters */
} 

@Embeddable
public class Location implements LocationCapable {
    @Basic
    @NotNull
    private Double latitude;
    @Basic
    @NotNull
    private Double longitude;
    @Basic
    private List<String> geocells;

    /* getters and setters */
} 

Чтобы проверить это, у меня есть следующий тестовый пример JUnit:

    @Test
    public void testSave() throws Exception {
        City city = new City("testCity1", new Location(1d, 1d));
        cityDao.persist(city);
        assertNotNull(city.getId());
    }

cityDao.persist(city) делает просто jpaTemplate.persist(object);

И вкогда я пытаюсь сохранить эту сущность, я получаю следующее исключение:

Caused by: java.lang.IllegalArgumentException: out of field index :-1
    at com.myproject.model.Location.jdoProvideField(Location.java)
    at org.datanucleus.state.JDOStateManagerImpl.provideField(JDOStateManagerImpl.java:2585)
    at org.datanucleus.state.JDOStateManagerImpl.provideField(JDOStateManagerImpl.java:2555)
    at org.datanucleus.store.mapped.mapping.CollectionMapping.postInsert(CollectionMapping.java:91)
    at org.datanucleus.store.mapped.mapping.EmbeddedPCMapping.postInsert(EmbeddedPCMapping.java:104)
    at org.datanucleus.store.appengine.DatastoreRelationFieldManager.runPostInsertMappingCallbacks(DatastoreRelationFieldManager.java:217)
    at org.datanucleus.store.appengine.DatastoreRelationFieldManager.access$200(DatastoreRelationFieldManager.java:48)
    at org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.apply(DatastoreRelationFieldManager.java:116)
    at org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelations(DatastoreRelationFieldManager.java:81)
    at org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations(DatastoreFieldManager.java:955)
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.storeRelations(DatastorePersistenceHandler.java:546)
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostProcess(DatastorePersistenceHandler.java:304)
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:256)
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:240)
    at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3185)
    at org.datanucleus.state.JDOStateManagerImpl.flush(JDOStateManagerImpl.java:4513)
    at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:2814)
    at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:2754)
    at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:2893)
    at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:369)
    at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:256)
    at org.datanucleus.jpa.EntityTransactionImpl.commit(EntityTransactionImpl.java:104)
    at org.datanucleus.store.appengine.jpa.DatastoreEntityTransactionImpl.commit(DatastoreEntityTransactionImpl.java:55)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
    ... 41 more
...