Java 如何在broadleaf中获取entityManager的静态实例?
这个问题是专门针对阔叶商业的。 我必须在静态方法中加载一个实体。由于注入entityManager没有帮助(因为我无法在静态方法中访问它),所以我无法加载实体 我尝试使用Persistence.createEntityManagerFactory,但没有帮助。 这是我的示例代码Java 如何在broadleaf中获取entityManager的静态实例?,java,hibernate,jpa,broadleaf-commerce,Java,Hibernate,Jpa,Broadleaf Commerce,这个问题是专门针对阔叶商业的。 我必须在静态方法中加载一个实体。由于注入entityManager没有帮助(因为我无法在静态方法中访问它),所以我无法加载实体 我尝试使用Persistence.createEntityManagerFactory,但没有帮助。 这是我的示例代码 Query query = Persistence.createEntityManagerFactory("blPU").createEntityManager().createQuery("some query");
Query query = Persistence.createEntityManagerFactory("blPU").createEntityManager().createQuery("some query");
List results = query.getResultList();
我得到的错误是:-
javax.persistence.PersistenceException: No Persistence provider for EntityManager named blPU
当我必须在实例方法中正常使用entityManager时,entityManager就像一个符咒:
@PersistenceContext(unitName="blPU")
protected EntityManager em;
所以我想这不是任何类路径问题。
任何帮助都会很好。如果您实际上不需要在静态上下文中编写查询,但仍然希望在静态方法中访问实体,我建议您使用以下通用代码通过CDI上下文查找EJB的现有实例:
public class Util {
private static <T> T lookUpClassInBeanManager(Class<T> clazz) {
BeanManager bm = CDI.current().getBeanManager();
Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next();
CreationalContext<T> ctx = bm.createCreationalContext(bean);
return (T) bm.getReference(bean, clazz, ctx);
}
public static YourDaoClass lookUpYourDaoClass() {
return lookUpClassInBeanManager(YourDaoClass.class);
}
}
公共类Util{
专用静态T lookUpClassInBeanManager(类clazz){
BeanManager bm=CDI.current().getBeanManager();
Bean=(Bean)bm.getBeans(clazz.iterator().next();
CreationalContext ctx=bm.createCreationalContext(bean);
return(T)bm.getReference(bean、clazz、ctx);
}
公共静态YourDaoClass查找YourDaoClass(){
返回lookUpClassInBeanManager(YourDaoClass.class);
}
}
您的类看起来是这样的:
@Stateless
public class YourDaoClass {
@PersistenceContext(unitName = "blPU", type = PersistenceContextType.TRANSACTION)
protected EntityManager em;
public <T> List<T> getEntityListByType(Class<T> clazz) {
TypedQuery<T> query = em.createQuery("select entity from "+ clazz.getSimpleName() +" entity", clazz);
return query.getResultList();
}
}
public static void tryEJBinStaticContext() {
YourDaoClass dao = Util.lookUpYourDaoClass();
List<SomeEntity> list = dao.getEntityListByType(SomeEntity.class);
}
@无状态
公共类{
@PersistenceContext(unitName=“blPU”,type=PersistenceContextType.TRANSACTION)
受保护的实体管理器em;
公共列表getEntityListByType(类clazz){
TypedQuery query=em.createQuery(“从“+clazz.getSimpleName()+”entity“,clazz”中选择实体);
返回query.getResultList();
}
}
在静态方法中,可以这样使用:
@Stateless
public class YourDaoClass {
@PersistenceContext(unitName = "blPU", type = PersistenceContextType.TRANSACTION)
protected EntityManager em;
public <T> List<T> getEntityListByType(Class<T> clazz) {
TypedQuery<T> query = em.createQuery("select entity from "+ clazz.getSimpleName() +" entity", clazz);
return query.getResultList();
}
}
public static void tryEJBinStaticContext() {
YourDaoClass dao = Util.lookUpYourDaoClass();
List<SomeEntity> list = dao.getEntityListByType(SomeEntity.class);
}
publicstaticvoid tryEJBinStaticContext(){
YourDaoClass dao=Util.lookUpYourDaoClass();
List List=dao.getEntityListByType(SomeEntity.class);
}
要清楚,在期间获得EntityManager工厂
是个坏主意。在企业容器内部创建EntityManager工厂
,改用容器功能。如果您需要容器外部的Peristence.createEntityManagerFactory
,例如,仅出于测试或其他原因。您必须创建JavaSEJPA上下文,我创建此上下文是为了解释如何进行JPA测试
这里有一些项目通知,如果你打算自己做的话,可以让你更好地理解
最重要的部分是只创建一个persistence.xml
,避免为测试创建另一个,而是覆盖您的persistence.xml
设置。这对于您persistence.xml应该足够了:
<persistence-unit name="application-ds" transaction-type="JTA">
<jta-data-source>java:/youApplication</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
下一个技巧是如何将持久性提供者注入ejb,mockito就是解决方案。代码优先:
@InjectMocks
private UserDao dao;
@Spy
private EntityManager em;
@Before
public void prepare() {
em = JpaProvider.instance().getEntityManager();
initMocks(this);
}
说明:Mockito用于将实体管理器注入ejb。将EntityManager标记为spied对象,并在测试方法之前的@中初始化它,然后在测试类上调用initMocks
,仅此而已。
最后但并非最不重要的一点是,不要忘记创建和提交事务,因为您没有容器来为您执行这些操作。特定于Broadleaf的答案(如果您需要blPU EntityManager)是使用:
GenericEntityDaoImpl.getGenericEntityDao().getEntityManager();
您可以注入静态entityManager,但这似乎不是一个好主意。您可以在这里和这里看到示例和备选方案