应该关闭 JPA 实体管理器吗? [英] Should JPA Entity Manager be closed?

查看:31
本文介绍了应该关闭 JPA 实体管理器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的方法.

public Profile readUser(String email){
    EntityManager em = EMF.get().createEntityManager();
    return em.find(Profile.class, email);
}

上面实体管理器的用法好吗?或者有必要关闭它们吗?请提供任何建议.

Is the above usage of entity manager okay? Or It is necessary to close em?Any suggestions please.

推荐答案

我想答案是:这取决于.

您的实体管理器是访问实体所在上下文的关键.如果您的应用程序是 JSE 应用程序,则必须考虑上下文的​​预期寿命是多少.

Your entity manager is the key to gain access to the context where entities reside. If your application is a JSE application, you have to consider what is the life expectancy of your context.

假设您将根据用户的请求创建一个实体管理器.因此,在您处理给定请求时,您将保持实体管理器打开,并在完成后关闭它.

Let's consider that you will create an entity manager per user's request. So, while you are attending a given request, you will keep your entity manager open, and when you finish with it, you close it.

在 JSE 应用程序中,您可能考虑过希望实体管理器在应用程序的整个生命周期内保持打开状态(假设您不处理大量数据),然后在应用程序关闭时关闭它.

In a JSE application, you may have considered that you would like to keep your entity manager open the entire life of the application (supposing you're not dealing with big amounts of data) then you close it when your application shuts down.

最重要的是,何时打开和何时关闭完全取决于您的策略和设计.当您不再需要其上下文中的实体时,您可以关闭它.

Bottom line, when you open it and when you close depends entirely on your strategy and your design. You close it when you no longer need the entities in its context.

在您的示例中,这并不明显,但是由于您正在方法中创建 EM,您应该在返回之前关闭它,否则,您将无法再次访问它(除非您将它保留在一些注册表,在代码中不明显).

In your example, that is not evident, but since you're creating the EM in the method, you should close it before returning, otherwise, you will no longer have access to it again (unless you're keeping it in some registry, which is not evident in the code).

如果您不关闭它,您的实体将保持为附加状态,即使在您使用完它们之后也是如此.即使您无法再访问您的 EM,您的上下文也会保持活动状态.

If you don't close it your entities will be kept as attached, even after you're done using them. Your context will be kept alive even when you can no longer access your EM.

JPA 规范包含更多详细信息.在 7.7 Application-managed Persistence Contexts 部分,它说:

The JPA Specification contains more details. In section 7.7 Application-managed Persistence Contexts it says:

当使用应用程序管理的实体管理器时,应用程序直接与持久化提供者的实体管理器交互工厂管理实体管理器生命周期并获取和销毁持久化上下文.

When an application-managed entity manager is used, the application interacts directly with the persistence provider's entity manager factory to manage the entity manager lifecycle and to obtain and destroy persistence contexts.

所有此类应用程序管理的持久化上下文都在范围,并且可以跨越多个事务.

All such application-managed persistence contexts are extended in scope, and can span multiple transactions.

EntityManagerFactory.createEntityManager 方法和EntityManager closeisOpen 方法用于管理应用程序管理的实体管理器及其关联的生命周期持久化上下文.

The EntityManagerFactory.createEntityManager method and the EntityManager close and isOpen methods are used to manage the lifecycle of an application-managed entity manager and its associated persistence context.

扩展持久化上下文存在于实体管理器已使用创建EntityManagerFactory.createEntityManager 直到实体管理器被通过 EntityManager.close 关闭.

The extended persistence context exists from the point at which the entity manager has been created using EntityManagerFactory.createEntityManager until the entity manager is closed by means of EntityManager.close.

从应用程序管理的扩展持久化上下文中获取实体管理器是一个独立的持久化上下文,它不是与交易一起传播.

An extended persistence context obtained from the application-managed entity manager is a stand-alone persistence context it is not propagated with the transaction.

[...] EntityManager.close 方法关闭实体管理器以释放其持久化上下文和其他资源.调用后关闭,应用程序不得调用任何进一步的方法EntityManager 实例,除了 getTransactionisOpen,或IllegalStateException 将被抛出.如果关闭方法是当事务处于活动状态时调用,持久化上下文仍然存在管理直到交易完成.

[...] The EntityManager.close method closes an entity manager to release its persistence context and other resources. After calling close, the application must not invoke any further methods on the EntityManager instance except for getTransaction and isOpen, or the IllegalStateException will be thrown. If the close method is invoked when a transaction is active, the persistence context remains managed until the transaction completes.

EntityManager.isOpen 方法指示实体管理器是否开了.isOpen 方法返回真,直到实体管理器已关闭.要真正了解其工作原理,了解实体管理器与上下文之间的关系至关重要.

The EntityManager.isOpen method indicates whether the entity manager is open. The isOpen method returns true until the entity manager has been closed. To actually understand how this works it is vital to understand the relationship between the entity manager and the context.

因此,正如您所看到的,实体管理器是您访问实体的公共接口,但是,您的实体驻留在上下文中,并附加到您的实体管理器.了解不同类型上下文的生命周期将回答您的问题.

So, as you can see the entity manager is the public interface through which you access your entities, however, your entities reside in a context, attached to your entity manager. Understanding the life cycle of the different types of contexts will answer your question.

持久化上下文可以是不同的类型.在 Java EE 应用程序中,您可以拥有事务范围的持久性上下文扩展持久性上下文.在 JSE 应用程序中,上下文的性质由开发人员控制.

Persistence contexts can be of different types. In Java EE applications, you can either have a transaction-scoped persistence context or a extended-persistence context. In the JSE application, the nature of the context is controlled by the developer.

当您向实体管理器请求实体时,它会在其附加上下文中查找该实体,如果在那里找到该实体,则返回该实体,否则,它会从数据库中检索该实体.在上下文中对该实体的后续调用将返回相同的实体.

When you ask for an entity to your entity manager, it looks for the entity in its attached context, if it finds the entity there, then it returns it, otherwise, it retrieves the entity from the database. Subsequent calls for this entity in context will return the same entity.

事务范围

在使用事务范围持久性上下文的 Java EE 应用程序中,当您第一次访问实体管理器时,它会检查当前 JTA 事务是否附加了上下文,如果尚不存在上下文,则会创建一个新上下文并创建实体manager 与此上下文相关联.然后从数据库中读取实体(如果存在,则从缓存中读取)并将其放入上下文中.当您的事务结束(提交或回滚)时,上下文变得无效并且其中的任何实体都变得分离.这是无状态会话 bean 的经典场景.

In a Java EE application using the transaction-scoped persistence context, when you first access your entity manager, it checks if the current JTA transaction has a context attached if no context is yet present, a new context is created and the entity manager is linked to this context. Then the entity is read from the database (o from the cache if present) and it is placed into the context. When your transaction ends (commit or rollback), the context becomes invalid and whatever entities in it become detached. This is the classical scenario for stateless sessions beans.

@PersistenceContext(unitName="EmplService")
EntityManager em;

这也意味着根据您设计交易的方式,您最终可能会遇到多个上下文.

This also means that depending on how you design your transactions, you may end up with more than one context.

扩展持久性上下文

在具有状态会话 bean 的 Java EE 应用程序中,您可能希望上下文能够在多次 bean 调用中存活,因为您不喜欢在 bean 被标记为删除之前提交,对吗?在这些情况下,您需要使用扩展的持久性上下文.在这种情况下,持久化上下文会在第一次需要时创建,但在您将有状态 bean 标记为删除之前它不会失效.

In a Java EE application with stateful session beans you might like the context to survive multiple bean invocations, since you don't like to commit until the bean has been marked for removal, right? In those cases, you need to use an extended persistence context. In this case, the persistence context is created when it is first needed, but it won't become invalid until your mark the stateful bean for removal.

@PersistenceContext(unitName="EmplService", type=PersistenceContextType.EXTENDED)

这意味着,无论在有状态会话 bean 方法的后续调用中注入此 bean 的实体管理器实例如何,您都可以确定您将始终访问相同的上下文,因此,即使后续调用也将返回相同的实例,因为它是相同的上下文.

This means that, regardless of the instance of the entity manager that gets injected into this bean in subsequent calls of the stateful session beans methods, you can be sure you will always access the same context, and therefore, even subsequent calls will return the same instance, because it is the same context.

此外,在 bean 被标记为删除或您手动刷新它们之前,您的更改不会被刷新.

Also, your changes will not be flushed until the bean is marked for removal or you manually flush them.

应用管理

您始终可以手动实例化您的实体管理器工厂和实体管理器.这是您在 JSE 应用程序中通常会做的事情,对吗?

You can always instantiate manually your entity manager factory and your entity manager. This is what you would typically do in a JSE application, is that right?

对于此类应用程序,您通常没有容器来处理 JTA 事务,对吗?因此,您使用资源本地事务并负责手动提交或回滚更改.

For this kind of applications you typically do not have a container to deal with the JTA transactions, right? So you use resource-local transactions and you are responsible for manually committing or rolling back changes.

对于这种应用程序,当您实例化实体管理器时,上下文会自动附加到它.

For this kind of application, when you instantiate your entity manager, a context is automatically attached to it.

根据您的应用程序,您可以决定创建一个全局实体管理器,其生命周期与应用程序本身的生命周期相关联.这是应用程序整个生命周期的单个实体管理器.在这种情况下,您的上下文将与您的实体管理器一起创建和销毁.

Depending on your application, you can decide to create a global entity manager whose life cycle is attached to the life of the application itself. That is a single entity manager for the entire life of the application. In this cases, your context will be created and destroyed with your entity manager.

或者,您可以为每个与应用程序用户的对话(即交易)创建一个实体管理器.在这种情况下,范围由您决定,但您的上下文仍然会由您的实体管理器创建和销毁.

Or, you could create an entity manager per conversation (i.e. transaction) with your application user. The scope, in this case, is determined by you, but still, your context will be created and destroyed with your entity manager.

这篇关于应该关闭 JPA 实体管理器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆