objectuser.blog(brain)

objectuser.getBlog().contains(anything)

  • a place for thoughts, explanations, etc.

    this is just a place to write things out so I can make sure i understand them, keep track of them, and to use them again as links, etc.
  • Subscribe

Spring + JDO in Google App Engine

Posted by objectuser on June 30, 2009

I had previously blogged about my setup with JPA and Google App Engine.  So far I have a big caveat for these setups … I’ve been doing most of this locally and what works locally does not have to work when you publish to GAE.  Specifically there are still JNDI errors when publishing.

However, this setup has been deployed.  But there is a bug in GAE that keeps it from working.  I’m still exploring a work-around.

Why did I switch from JPA to JDO?  One reason: JDO has a better feature set when working with GAE.

I had to google around a bit, read some manuals and do some trial and error to get this to work.  I thought I’d put it all together in case it helped someone else or someone could critique it with a better way, etc.

First, follow the Google documentation about setting up JDO in GAE.

Next, tie your JDO setup in GAE to Spring.

<bean id="persistenceManagerFactory"
    class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean">
<property name="persistenceManagerFactoryName" value="transactions-optional" />
</bean>

Now setup the transaction proxy so they’ll work with Spring’s AOP-style transactions:

<bean id="persistenceManagerFactoryProxy" class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy">
<property name="targetPersistenceManagerFactory" ref="persistenceManagerFactory" />
<property name="allowCreate" value="false" />
</bean>

<bean id="transactionManager">
<property name="persistenceManagerFactory" ref="persistenceManagerFactoryProxy" />
</bean>

Finally, let Spring inject the PersistenceManagerFactory into your DAOs.

<bean id="userDao" class="my.app.integration.jdo.JdoUserDao" scope="singleton">
<property name="persistenceManagerFactory" ref="persistenceManagerFactoryProxy"/>
</bean>

Here is how to setup transactions:

<aop:pointcut id="myJdoMethods" expression="execution(* my.app.integration.jdo.*.*(..))" />
  <aop:pointcut id="myServiceMethods" expression="execution(* my.app.*.*(..))" />
  <aop:advisor advice-ref="txAdvice" pointcut-ref="myJdoMethods" />
  <aop:advisor advice-ref="txAdvice" pointcut-ref="myServiceMethods" />
</aop:config>

I’m trying to figure out if only update operations should have a transaction.  Currently, I have find methods that fail within a transaction, so I have them excluded.

Advertisements

34 Responses to “Spring + JDO in Google App Engine”

  1. […] Software Development « Spring + JDO in Google App Engine […]

  2. Graham Lea said

    Thanks for posting this.
    I think there’s a typo?

    I think should refer to jdoTransactionManager, right?

    • objectuser said

      You’re probably right, Graham. I’m “away” from my code, but that makes sense.

      Thanks! I’ll fix it when I get back.

  3. Corby Page said

    When you are using this configuration, don’t you hit the GenericSignatureFormatError that you described on the mailing list? Or, have you found a workaround for this?

    • objectuser said

      In the second paragraph I mention that very defect. No work-around as yet, but I’ve not had time to try removing generics from the signature of the methods (which is the suggestion I received in that post).

      It seems like it’s worth a shot. Would you be willing to try it?

      • Corby Page said

        I gave it a try. I had a simple app with four DAO methods that were advised by the Transaction interceptor. I removed generics from the method signature of all four DAO methods, but I got the same result.

        To be clear, I don’t have any problem on the local development server. I only get the GenericSignatureFormatError when I try to instantiate the Application Context on Google App Engine.

        I think other people have reported problems with @Configurable, so AspectJ weaving in general appears to be a no-go in this environment.

        • objectuser said

          Thanks for trying it! That’s very interesting (and very unfortunate).

          I’m in the same situation: everything works in the SDK but not on the server.

          Are you going to reply to that defect? It might be very important information for them.

          I’m not sure how best to get around it other than using explicit transactions, or one of the JDO template class solutions (which I find very intrusive).

  4. nwallman said

    Thanks for the input. I am having trouble getting this working with Spring 3.0M3 and I was wondering if you could post a sample app where you have JDO working. I just want to compare my setup with yours and confirm that the problem isn’t my setup but something with Spring 3.0.

    Thanks very much!

    Nate

    • objectuser said

      I think there are some sample apps out there. You might search the GAE Google group. It would take me a while to post a sample … not good for either of us if there’s already one available. 🙂

      What problems are you having specifically?

      • nwallman said

        I can’t recall the specific error because I eventually gave up and wired it manually. Basically I was trying to use your configuration above and it was blowing up. For starters on this:

        1.
        2.
        3.

        It says I have to define a class. So I added the the PMF class that the GAE documents describe and that doesn’t work either. Is your applicationContext.xml just like this or did you leave out parts to manually configure? Please forgive me, I’m new to Spring and JDO so I’m learning as I go.

        And as far as sample projects I have found numerous ones but none of them show using Spring ORM to handle persistence. Thanks!

      • nwallman said

        Nice my code posting was filtered. Let me try this again…

        • objectuser said

          Silly wordpress … sorry about that. You might want to just format by hand.

          My configuration is really close to what’s in this post (names change, etc.). But I don’t think there’s much more to it.

          You have your JDO configuration setup like in the link, where transaction-optional is originally defined?

          Generally, I wonder if Spring 3 is just a lot different …

  5. nwallman said

    My JDO config file is the default one that the Google Plugin creates when you create a new Google Web Application project. I know that is working correctly because I am able to persist things. Secondly I have created PersistenceManagerFactory just like the Google JDO documentation recommends. So the next step was to try and use Spring’s IOC to wire up the dependencies in my classes.

    This mapping: bean id=”persistenceManagerFactory” blows up because there isn’t a class field defining it. So when I tried to use the javax.jdo.PersistenceManagerFactory it says its an interface so I can’t use that. I can’t use the PMF class(defined by JDO docs) because that doesn’t implement that interface.

    So I wonder how spring knows to get the class definition for “persistanceManagerFactory” if it isn’t defined in applicationContext.xml? Are you somehow linking your JDO config file into your application context? That’s why I was interested in seeing your code so I could see the whole applicationContext.xml and see if I’m missing something obvious.

    Thanks for your continued help by the way!

    • objectuser said

      Okay, I think the “class” part of this definition got cut off. I’ll update the post. Is that the issue?

      	<bean id="persistenceManagerFactory"
      		class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean">
      		<property name="persistenceManagerFactoryName" value="transactions-optional" />
      	</bean>
      
      • Nwallman said

        I haven’t had a chance to give this a try. I will probably add the spring wiring when I get around to adding transactions. Thanks for your help and I’ll reply back when I confirm if this works in the near future.

  6. asianCoolz said

    can you share tutorial on how to write my.app.integration.jdo.JdoUserDao ?

    • objectuser said

      JdoUserDao would just use the JDO API. Nothing really interesting or different in there. The Google documentation would be a good place to start.

  7. asianCoolz said

    In your article u mentioned “have find methods that fail within a transaction, I have find methods that fail within a transaction, so I have them excluded.”

    but from google documentation http://code.google.com/appengine/docs/java/datastore/transactions.html “Using Transactions” . the pm.getObjectById(ClubMembers.class, “k12345”);
    is wrapped inside transaction. can comment on this? whether should use trasaction when retrieve result from datasource?

    • objectuser said

      My current understanding is that all datastore operations take place in a transaction.

      I don’t quite remember the specific issues I was having at the time. But for transactions you need to make sure you don’t access more than one entity group. So I often put “not supported” around finders so they will have a new implicit transaction created and committed and that transaction won’t affect my larger transaction.

      Does that make sense? And does it answer your question?

  8. asianCoolz said

    aop not supported by appengine, so the above code will not work right?

    #

    • objectuser said

      Right, note my “bug” reference at the beginning.

    • Note said

      If AOP doesn’t support on GAE, why does my JPA setting with Spring (3.0.M4) work just fine?
      Now, I’m trying to change from JPA to JDO. I had a bug before. I’m not sure my second try would work or not. If it doesn’t I’d just following the GAE tutorial. Which is too much work and I’m totally lazy.. lol

      • objectuser said

        Have you tried running it on the host? For me, it works in the development environment but not on the host. If it works, I want to know what you did! 🙂

  9. Note said

    I think GAE Server doesn’t like PersistenceManagerProxy. I remove it and everything works fine on GAE Server now.

      
      
    
    
      
      
     
    
      
      
    
    

    I’m using on my applicationContext-service.xml and put @Tranaction on userDaoImpl.class that implements userDao Interface.

    Maybe you should try and see if it works too. Thank for the Wicket on GAE article by Nick Wiedenbrueck.

    ps. Objectuser could you delete the comment 9 and 10. Thanks

    • objectuser said

      It makes sense that GAE would not like the *Proxy class because that’s the point of AOP tie-in. Without that, you won’t be getting any sort of declarative transaction management. So you’re back to either having no “span” on your transactions, having to use the JDOTemplate, or managing transactions explicitly. Is that correct?

      (Deleted the other two comments … sorry about the code formatting thing … no idea why WordPress strips that stuff out.)

    • Note said

      Actually all the codes stay the same. I have removed @Transaction from persistence class (userDaoImpl) because I’ve got errors when I was trying to persist entity that has child entities. I manage my transaction as your code above. That’s all.

      Here is my userDaoImpl looks like: (I also use context:component-scan)

      @Repository
      Class userDaoImpl implements userDao() {

      @Autowired
      private PersistenceManagerFactory persistenceManagerFactory;

      private PersistenceManager getPersistenceManager() {
      return persistenceManagerFactory.getPersistenceManager();
      }

      public void save(User user) {
      getPersistenceManager().makePersistent(user);
      }
      }

      In my service layer. I just have to autowired it. That’s all.

      Class UserServiceImpl implements UserService {

      @Autowired
      private UserDao userDao;


      }

      Ps.. I tried to put some codes but it didn’t work.. Sorry..

      • objectuser said

        I get what you’re saying, but I don’t see how transactions are going to work without that transaction-aware proxy. I mean, you’ll still be able to save stuff, but each interaction with the datastore will be in its own transaction. At least, that’s what it looks like to me.

        Have you tried to prove that you still have a transaction that spans writes in a particular entity group?

      • Note said

        What do you mean by having a transaction that spans writes in a paritcular entity? Give me an example.

        • objectuser said

          Let’s see … how about the typical banking example.

          class CustomerAccount {
          Account checking;
          Account savings;
          }

          class Account {
          double balance;
          }

          If you have a transaction that spans writes in a particular CustomerAccount, you can transfer balance from savings to checking, saving each one in turn and if one fails, the other rolls back. So just a typical transaction in other databases.

          Without that proxy, I think every write you make will be in its own transaction.

          • Note said

            Sorry for the late reply. I’ve been busy experiment with entities key. It’s very confused. Anyway, I don’t think that’s gonna work (roll back). I think that every transactions is separated from each other like you thought. xD

  10. […] use an approach similar to the one Objectuser describes in his post. It really is a piece of cake, you just set up a LocalPersistenceManagerFactoryBean to point to the […]

  11. Oscar Wu said

    part of my spring setting is like below:

    I got error message which points my setting wrong here:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao' defined in class path resource [spring-dao.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy2 implementing javax.jdo.PersistenceManagerFactory,javax.naming.spi.ObjectFactory,javax.naming.Referenceable] to required type [org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy] for property 'pmfProxy'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy2 implementing javax.jdo.PersistenceManagerFactory,javax.naming.spi.ObjectFactory,javax.naming.Referenceable] to required type [org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy] for property 'pmfProxy': no matching editors or conversion strategy found

    this is part of my java code on UserDao.java

    public class UserDao {
    private TransactionAwarePersistenceManagerFactoryProxy pmfProxy;
    private PersistenceManagerFactory pmf;
    private PersistenceManager pm;
    ...
    public void setPmfProxy(TransactionAwarePersistenceManagerFactoryProxy p) {
    this.pmfProxy = p;
    }
    public TransactionAwarePersistenceManagerFactoryProxy getPmfProxy() {
    return pmfProxy;
    }

    So what have I done is wrong leads to this?

    • objectuser said

      I’m not sure why you have TransactionAwarePersistenceManagerFactoryProxy wired in at all. It’s a proxy that implements the PersistenceManagerFactory. You might want to review the Spring documentation. I think that’s the source of your trouble.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: