使用JDO的Grails - 如何正确使用persistenceManager

时间:2010-06-14 12:23:00

标签: google-app-engine grails jdo

我正在使用谷歌应用引擎和Grails创建一个应用程序。我为我的Flex应用程序设置了一个Controller来调用。 Controller调用服务以获取列表并将其发送回Flex。

Flex客户端能够重新获取一次数据。此外,如果我在浏览器中调用该操作,我也可以调用该操作并获取数据。我发现的问题是它不能多次调用它,因为应用程序正在使用JDO,并且在第一次调用后我收到错误,说明persistenceManager已经关闭。

我已经阅读了一些帖子,向您展示如何设置一个吨,并在需要时获取persistanceManager的实例,但这似乎也不起作用。

这是我第一次使用JDO,我可以使用一些建议,让这些服务在一致的基础上工作。

以下是实际查询数据存储区的服务的代码。

package com.dlish.fulcrum

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

    }
}

2 个答案:

答案 0 :(得分:0)

这与我的Controller代码非常相似。除了我不使用transactional = true,你为什么要这样做你只是在阅读?您使用的是哪个版本的app-engine插件?

这是我的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>

答案 1 :(得分:0)

grails app-engine插件在请求范围中创建persistenceManager对象。默认情况下,服务是单例,这意味着它们只创建一次而不是按请求创建。因此,如果您为服务提供persistenceManager实例变量,则第一个请求将具有有效的persistenceManager,但所有后续调用将具有关闭的persistenceManager,因为您的服务仍然从第一个请求引用管理器。

有两种方法可以解决这个问题:

1)更改服务范围。您可以通过在服务类中放置以下内容来完成此操作:

static scope = "request"

2)在调用服务方法

时,将persistenceManager从控制器传递给服务