开发者

grails with JDO - how do I work with persistenceManager correctly

I am creating an application with google app engine and grails. I have a Controller set up for my Flex application to call. The Controller calls a service to get a list back and send it back to Flex.

The Flex client is able to get the data back one time. Also If I call the action in the browser I can call the action and get data back as well. The problem that I am finding is that it is not able to call it more than once because the app is using JDO and after the first call I get an error saying that the persistenceManager has been closed.

I have read some posts that show you how to set up a single ton and just get an instance of the persistanceManager when you need it but this does not seem to work either.

This is my first time working with JDO and I could use some advice one getting these services to work on a consistant bases.

Here is the code from the service that is actually querying the datastore.

package com.dlish.ful开发者_开发百科crum

import com.dlish.fulcrum.PMF
import org.springframework.beans.factory.InitializingBean
import com.google.appengine.api.datastore.*
import com.dlish.fulcrum.Show

class VenueBlastService {

    static transactional = true

    def grailsApplication
    def setting

    void afterPropertiesSet()
    {
        this.setting = grailsApplication.config.setting
    }

    def persistenceManager

    def getAllShows() {         

        def query = persistenceManager.newQuery( Show )
        def  showInstanceList = query.execute()

        return showInstanceList

    }
}


The grails app-engine plugin creates the persistenceManager object in the request scope. By default, services are singletons, which means they are created once instead of per request. Thus, if you give your service a persistenceManager instance variable, the first request will have a valid persistenceManager, but all subsequent calls will have a closed persistenceManager, because your service is still referencing the manager from the first request.

There are two ways to fix this:

1) Change the scope of your service. You can do this by placing the following in your service class:

static scope = "request"

2) pass the persistenceManager from your controller to the service when you call the service method


This is very similar to my Controller's code. Except I don't use the transactional = true, why do you want this you're only doing a read? What version of the app-engine plugin are you using?

Here's my jdoconfig.xml:

<?xml version="1.0" encoding="utf-8"?>

<persistence-manager-factory name="transactions-optional">
    <property name="javax.jdo.PersistenceManagerFactoryClass"
        value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
    <property name="javax.jdo.option.ConnectionURL" value="appengine"/>
    <property name="javax.jdo.option.NontransactionalRead" value="true"/>
    <property name="javax.jdo.option.NontransactionalWrite" value="true"/>
    <property name="javax.jdo.option.RetainValues" value="true"/>
    <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜