views:

899

answers:

1

Why am I receiving the exception below if the type of both entities is PersistentLogin? I thought that would mean they are in the same entity group, but I guess that is an incorrect assumption. Any ideas how to fix this?

This is the code:

// the class is marked with @Transactional
@Override
public final void removeUserTokens(final String username) {
    final Query query = entityManager.createQuery(
        "SELECT p FROM PersistentLogin p WHERE username = :username");
    query.setParameter("username", username);

    for (Object token : query.getResultList()) {
        entityManager.remove(token);
    }
}

This is the exception:

Caused by: javax.persistence.PersistenceException: Illegal argument
    at org.datanucleus.jpa.NucleusJPAHelper.getJPAExceptionForNucleusException(NucleusJPAHelper.java:260)
    at org.datanucleus.jpa.EntityTransactionImpl.commit(EntityTransactionImpl.java:122)
    at org.datanucleus.store.appengine.jpa.DatastoreEntityTransactionImpl.commit(DatastoreEntityTransactionImpl.java:50)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
    ... 42 more
Caused by: java.lang.IllegalArgumentException: can't operate on multiple entity groups in a single transaction. found both Element {
  type: "PersistentLogin"
  name: "1WfCYx8bmwUGkjzP2PpmFA=="
}
 and Element {
  type: "PersistentLogin"
  name: "SfI0P8RVBjTvu0WHMSuaVA=="
}
+2  A: 

Same entity group means that the entities have a common parent entity.

Two top-level entities are never in the same entity group.

Any ideas how to fix this?

The easiest way is to relax the transaction requirements. In your case that would mean deleting the PersistentLogin entities one by one (best effort loop, delete as much as you can, retry on errors, no guarantee of atomicity).

If you wanted to put the PersistentLogin for the same user in the same entity group, you would need to make rather big changes to your data model, with uncertain impact on overall performance.

With non-relational databases, you have to code your application without relying on transactions on the data store. They just do not support them to the extent that we have become used to.

Thilo
The problem I have is that when I make my method or class not have @Transactional then I get the following exception: org.datanucleus.exceptions.NucleusUserException: Object Manager has been closed
Taylor Leese
See this question I posted: http://stackoverflow.com/questions/2294867/google-app-engine-org-datanucleus-exceptions-nucleususerexception-object-manag
Taylor Leese