Tuesday Jun 23, 2009

Buggy JPA support in Google App Engine

I wanted to develop application that allows me to track my running log on the web. Also, I wanted test NetBeans Google App Engine plugin that I was working in the last weeks. Since, I'm familiar with JPA I choose this datastore for my application and created the simple Activity entity class like this (app is hosted here):
    @Entity
public class Activity implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    private ActivityType type;
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar start;
    private int avgheartRate;
    private long duration;

    public Activity() {
        
    }
 
Then, I implemented facade class that access datastore and persist activity in database:
     public void createActivity(ActivityType type, Calendar start,
            int avgheartRate, long duration) {
        EntityManager em = PersistenceFactory.getFactory().createEntityManager();
        Activity activity = new Activity(type, start, avgheartRate, duration);
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.persist(activity);
            tx.commit();
        } catch (Exception ex) {
            if(tx != null && tx.isActive())
            tx.rollback();
            Logger.getLogger(this.getClass().getCanonicalName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
        } finally {
             em.close();
        }
    }
 
Google App Engine has very nice support for unit testing hence I wrote simple test for above method and run tests. However, I got following exception:
 java.lang.UnsupportedOperationException
        at org.datanucleus.store.appengine.EntityUtils.getPropertyName(EntityUtils.java:60)
        at org.datanucleus.store.appengine.DatastoreFieldManager.getPropertyName(DatastoreFieldManager.java:872)
        at org.datanucleus.store.appengine.DatastoreFieldManager.storeObjectField(DatastoreFieldManager.java:757)
        at org.datanucleus.state.AbstractStateManager.providedObjectField(AbstractStateManager.java:1011)
        at org.mujbeh.model.Activity.jdoProvideField(Activity.java)
        at org.mujbeh.model.Activity.jdoProvideFields(Activity.java)
        at org.datanucleus.state.JDOStateManagerImpl.provideFields(JDOStateManagerImpl.java:2597)
        at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:180)
        at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3067)
        at org.datanucleus.state.JDOStateManagerImpl.flush(JDOStateManagerImpl.java:4395)
        at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:2807)
        at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:2747)
        at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:2886)
        at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:348)
        at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:235)
        at org.datanucleus.jpa.EntityTransactionImpl.commit(EntityTransactionImpl.java:104)
        at org.mujbeh.PersistenceFacadeImpl.createActivity(PersistenceFacadeImpl.java:37)
        at org.mujbeh.PersistenceFacadeImplTest.testCreateActivity(PersistenceFacadeImplTest.java:31)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:232)
        at junit.framework.TestSuite.run(TestSuite.java:227)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:515)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1031)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:888)
 
I spent almost one hour on debugging and finding the issue in my code but without any success. Then, I found out that it's known issue that was reported in April 09. The issue and some workarounds that don't work for me are described here. There are many posts from users who encounter this issue in their applications. It seems as the stopper for Persistence in Google App Engine and totally blocks me to continue in my application. Above use cases is really crucial for every application that might be developed in Google App Engine. JPA support in Google App Engine SDK 1.2.1 is useless now.
About

pblaha

Search

Categories
Archives
« June 2009
SunMonTueWedThuFriSat
 
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
18
19
20
21
22
24
25
26
27
28
29
30
    
       
Today
Bookmarks