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

查看:115
本文介绍了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应用程序管理的持久性上下文部分中,它说:

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 close isOpen 方法用于管理应用程序管理的实体管理器的
生命周期及其关联的
持久化上下文。

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 方法将实体管理器关闭到
释放其持久性背景和其他资源。在调用
close之后,应用程序不得在
EntityManager 实例上调用任何其他方法,但 getTransaction isOpen ,或
将抛出 IllegalStateException 。如果在事务处于活动状态时调用close方法是
,则持久化上下文将保持
管理,直到事务完成。

[...] 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 方法返回true,直到实体管理器已关闭

要真正了解其工作原理,了解实体管理器与上下文之间的关系至关重要。

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事务是否附加了上下文,如果还没有上下文,则创建新上下文并且实体管理器链接到此上下文。然后从数据库中读取实体(如果存在,则从缓存中读取o),并将其放入上下文中。当您的事务结束(提交或回滚)时,上下文将变为无效,并且其中的任何实体都将被分离。这是无状态会话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.

扩展持久化上下文

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

In a Java EE application with stateful session beans you might like the context to survive multiple bean invocations, since you won't like to commit until the bean has been marked for removal, right? In those cases you need to use a 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 statefull bean for removal.

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

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

This means that, regardless of the instance of the entity manager that gets injected into this bean in subsequent calls of the statefull 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 of 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, you context will be created and destroyed with your entity manager.

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

Or, you could create a 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天全站免登陆