Guice Persist是否提供事务范围的或应用程序管理的EntityManager? [英] Does Guice Persist provide transaction scoped or application managed EntityManager?

查看:152
本文介绍了Guice Persist是否提供事务范围的或应用程序管理的EntityManager?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用 Guice Persist 将EntityManager注入我们的项目. /p>

例如

public class MyDao{
   @Inject
   EntityManager em;

   public void someMethod(){
       //uses em instance
   }
}

但是我们不清楚如何使用注入的EntityManager实例.

  1. 这是什么类型的EntityManager?(请参见例如:实体管理器的类型),Guice Persist在后台通过EntityManagerFactory.createEntityManager()实例化它,所以我想说它是应用程序管理的实体管理器.但是在官方Wiki 中,他们写了关于每次交易观看次数策略,这表明EntityManager是(伪)事务作用域的.
  2. 我们应该手动在其上调用close()吗?还是Guice会照顾好它?
  3. 一级缓存的范围是什么?仅单个事务(例如在事务范围的实体管理器中)还是只要我使用相同的EntityManager注入实例(例如在应用程序管理的实体管理器中)?

解决方案

我对Guice-persist的源代码进行了一些研究,并阅读了Guice-persist Wiki页面下的注释,这些是我需要的答案:

1.如果通过@Inject EntityManager进行注入,则EntityManager的生命周期管理将被破坏.如Wiki上的评论之一所述:

我确认直接注入EntityManager而不是提供者 可能很危险.如果您不在UnitOfWork或方法中 用@Transaction注释,这是EntityManager的第一次注入 在一个线程中将创建一个新的EntityManager,从不销毁它,并且 始终为此线程使用此特定EntityManager(存储了EM 线程本地).这可能会导致可怕的问题,例如注入 死了的entityManager(连接已关闭等),所以我的建议是 总是注入提供者,或者至少注入 仅在打开的UnitOfWork内部直接使用EntityManager.

所以我所问的例子不是最正确的用法.它创建EntityManager的单例实例(每个线程),并将该实例注入到各处:-(.

但是,如果我注入了Provider并在@Transactional方法中使用了Provider,则EntityManager的实例将是按交易的.因此,此问题的答案是:如果正确注入和使用,则实体管理器将具有事务作用域.

2. 如果注射和使用正确,则无需手动关闭实体管理器(guice-persist会为我处理).如果使用不当,手动关闭将是一个非常糟糕的主意(当我@Inject EntityManager时,将在每个位置注入EntityManager的关闭实例)

3. 如果正确注入和使用,则L1缓存的范围为单笔交易.如果使用不正确,则L1缓存的范围是应用程序的生命周期(EntityManager为单例)

We use Guice Persist to inject EntityManager in our project.

E.g.

public class MyDao{
   @Inject
   EntityManager em;

   public void someMethod(){
       //uses em instance
   }
}

But it is unclear for us how injected instance of EntityManager is about to be used.

  1. What type of EntityManager is this? (see e.g.: types of entity managers) Under the hood Guice Persist instantiates it via EntityManagerFactory.createEntityManager() so I'd say it's application-managed entity manager. But in official Wiki they write about seesion-per-transaction strategy, which suggests that EntityManager is (pseudo) transaction-scoped.
  2. Should we invoke close() on it manually? Or Guice will take care of it?
  3. What is the scope of first level cache? Only single transaction (like in transaction-scoped entity managers) or as long as I use the same injected instance of EntityManager (like in application managed entity managers)?

解决方案

I did some research of the source code of Guice-persist and read through comments under Guice-persist wiki pages and these are the answers that I needed:

1 . Lifecycle management of EntityManager is kind of broken if it's injected via @Inject EntityManager. As stated in one of the comments on the Wiki:

I confirm that inject directly an EntityManager instead of a provider can be dangerous. If you're not inside a UnitOfWork or a method annotated with @Transaction, the first injection of an EntityManager in a thread will create a new EntityManager, never destroy it, and always use this specific EntityManager for this thread (EM are stored thread-local). This can lead to terrible issues, like injection of dead entityManager (connection closed, etc) So my recommendation if to always inject a Provider, or at least to inject directly an EntityManager only inside an opened UnitOfWork.

So example in my question isn't the most correct usage. It creates singleton instance of EntityManager (per-thread) and will inject this instance everywhere :-(.

However if I've injected Provider and used it inside @Transactional method then the instance of EntityManager would be per-transaction. So the answer to this question is: if injected and used correctly, the entity manager is transaction-scoped.

2 . If injected and used correctly then I don't need to manualy close entity manager (guice-persist will handle that for me). If used incorrectly, closing manually would be very bad idea (closed instance of EntityManager would be injected in every place when I @Inject EntityManager )

3 . If injected and used correctly then the scope of L1 cache is single transaction. If used incorrectly, the scope of the L1 cache is the lifetime of application (EntityManager is singleton)

这篇关于Guice Persist是否提供事务范围的或应用程序管理的EntityManager?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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