This is my experience, warts and all, maybe it will help others. I'm using the eclipse plugin for development.
In my previous hack, I used JDO to see what it was like, I didn't much like it and decided to move back to JPA. I found JDO quite verbouse to use and especially did not like the way you have to declsre parameters for queries.
The first step was to create the persistance.xml file, as the eclipse plugin only provides the jdo configuration as default. Its easy enough, put it in the same place as your jdoconfig.xml file (in the META-INF directory).
You will need to identify the Entity classes by specifying them in the persistenace.xml file using the <class> tag.
See Setting Up JPA in the docs. Hmm, the line
EntityManager em = EMF.get().getEntityManager();
should be changed to:
EntityManager em = EMF.get()createEntityManager();
Wow! Changed the JDO persisted class to a JPA entity class by changing the annotations and implementing Serializable and.. it work!!
Edit the deployment descriptor (web.xml to you and me) and include the
security-constraint tag. There is an example in the docs called Security and Authentication.
See Google Accounts Java API Overview in the docs.
OK, then how does one access the user principal using EL in a JSP page?
Looking at the user principal I see it is implemented as: com.google.apphosting.utils.jetty.
UserServiceFactory.getUserService().getCurrentUser() which return a com.google.appengine.api.users.User object. There mus be some relationship to AppEnginePrincipal, but its not via inheritance.
Some digging around and I see AppEnginePrincipal holds an instance of User, so I can do this in JSP:
(of course, once the user is logged in)
Any resources specified in a security-constraint will cause a redirect to the google login page. Any User specified as a developer on the application will have admin role, not sure what role everybody else gets or how to get more roles.
The Turn Around
Under the persistance section I mentioned moving from JDO to JPA, I really don't like JDO from a usablility point of few, the stench is too high - I don't want to be that aware of my datastore.
But now I find myself going back to JDO for a number of reasons:
- Not enough documentation on GAEJ about using JPA
- The JPA implementation is basically JDO under the hood and I get the feeling not everything translates well.
- JDO is simpler for storing objects outside your domain (the User object springs to mind)
- There is a general ".. I don't know, use JDO.." attitude on the mailing list
- I plan to use GWT in the project and there are serious issues regarding serializing Entities - GWT-RPC broken in GAE/J.
The DataNucleus Enhancer is starting to T me off, keeps on popping up in the console after you save any class in your project, perhaps it should only be kicked off when saving persistant objects or not output unless on error.
Ah, got it: under your project properties -> google -> appengine -> ORM you can specify the specific file/ packages you want enhanced. Nice.
And we are back with JDO. The data hasn't changed, the same data was accessed by JDO, then JPA, then back to JDO without issue.
Then there is a gap where I modify my J2ME MIDlet, faf around with getting data from the phone and add a domain to my application and run out of bandwidth. This is not a happy period.
Implicit params in the JDO queries will be supported in the next release. Meh
The other 'Duh' drops
Spent a lot of time trying to figure out relationships and how to implement it with GAE. Did some more reading and recommend these articles: Re-thinking Object-Relational Mapping in a Distributed Key-Store world and How I Learned to Stop Worrying and Love Using a Lot of Disk Space to Scale. I've simplified my initial design dramatically and geared it towards my end goals and a (gasp!) de-normalized the design.
The thing that bothers me most is using JDO/JPA for something like this.I'm going to have a look at the lower level APIs and see if they make more sense (at some stage)
It would be nice to include a restart button for the local web host within eclipse.
Session support is not enabled in appengine-web.xml by default. To enable sessions, put <sessions-enabled>true</sessions-enabled> in that file.
I've read somewhere that read only session attributes are supported out the box, I guess that is why you have access to the UserPrincipal.
And while I'm on session:: it seems objects stored in the session must be serializable, not obvious under the test server, but going live will throw exceptions.
And you can view your applications sessions via the data viewer in the application administrator.
I finally understand why a lot of people are against pure servlet/JSP/taghandler development, they were probably using eclipse. A NetBeans GAEJ module would be nice.
Conclusion of Sorts
The major headache is around data access at the moment. Working with BigTable requires a mind change if your are used to relational databases.