grails 与 JDO - 如何正确使用 persistenceManager

发布于 2024-09-05 18:16:11 字数 989 浏览 2 评论 0原文

我正在使用谷歌应用程序引擎和 grails 创建一个应用程序。我设置了一个控制器供我的 Flex 应用程序调用。控制器调用服务来获取列表并将其发送回 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

    }
}

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.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

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如梦初醒的夏天 2024-09-12 18:16:11

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

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

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

static scope = "request"

2) 当您调用服务方法时,将 persistenceManager 从控制器传递到服务

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

机场等船 2024-09-12 18:16:11

这与我的控制器的代码非常相似。除了我不使用 transactional = true 之外,为什么你想要这个你只是在读?您使用的是哪个版本的应用程序引擎插件?

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

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>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文