使用Hibernate配置Spring JPA应用程序进行单元测试(延迟加载)

使用Hibernate配置Spring JPA应用程序进行单元测试(延迟加载),第1张

概述我在配置一个使用JPA和Hibernate进行单元测试的Spring应用程序时遇到问题.我有2个persistence.xml文件,一个用于生产,一个用于单元测试.用于检测:<?xml version='1.0' encoding='UTF-8'?> <persistence xmlns='http://java.sun.com/xml/n

我在配置一个使用JPA和Hibernate进行单元测试的Spring应用程序时遇到问题.
我有2个persistence.xml文件,一个用于生产,一个用于单元测试.
用于检测:

用于检测:

区别在于单元测试我不使用任何JTA(全局事务),我只使用本地事务.

生产的d簧配置是:

 

单元测试的d簧配置:

我花了相同的时间来决定这个配置,应用程序需要全局事务,因为我们在JMS和DB之间有事务,但在单元测试中我只定义了本地事务,所以我在测试应用程序时受到限制.
有了这个限制,我定义了我的单元测试.

现在我遇到了Hibernate和LAZY加载关系的问题.在单元测试中,EntityManager会话在查找方法之后关闭,然后LAZY加载的代理不起作用.(根据预期,这在Hibernate中是定义的)
我的问题是Bean PersistenceAnnotationBeanPostProcessor,它确实为单元测试设置了任何unitname,并且每当他找到注释@PersistenceContext时,他都会插入一个新的Entitymanger,该Entitymanger是从spring配置中定义的EntityManagerFactory创建的,用于测试.
现在,单元测试还有一个@PersistenceContext entityManager成员和DAO类:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"classpath:testConfiguration.xml"})@TransactionConfiguration(transactionManager = "transactionManager",defaultRollback = true)@Transactionalpublic class ConnectionTest {  @PersistenceContext  EntityManager entityManager;  Logger log = Logger.getLogger(ConnectionTest.class);  @Resource(name = "syDbVersionDao")  SyDbVersionDao dbVersionDao;  @Test  public voID testChanging() {    String oldVer = dbVersionDao.getCurrentVersion();    assertNotNull(oldVer);  }} @Component public class SyDbVersionDao extends SyDbVersionHome { @PersistenceContext private EntityManager entityManager;   public String getCurrentVersion() {      SyDbVersion res = getLastRecord();      if (res == null) return "";      return res.getVersion();   }   public SyDbVersion getLastRecord(){      query query = entityManager.createquery("from SyDbVersion v order by v.installationDate desc");      query.setMaxResults(1);      return (SyDbVersion) query.getSingleResult();   } } /** * Home object for domain model class SyDbVersion. * @see com.tsy@R_301_6563@s.ac.fIDs.web.persistence.jpa.SyDbVersion * @author Hibernate Tools,generated! */ @Stateless public class SyDbVersionHome {    private static final Log log = LogFactory.getLog(SyDbVersionHome.class);    @PersistenceContext private EntityManager entityManager;    public voID persist(SyDbVersion transIEntInstance) {      log.deBUG("persisting SyDbVersion instance");      try {        entityManager.persist(transIEntInstance);        log.deBUG("persist successful");      }      catch (RuntimeException re) {        log.error("persist Failed",re);        throw re;      }    }    public voID remove(SyDbVersion persistentInstance) {      log.deBUG("removing SyDbVersion instance");      try {         entityManager.remove(persistentInstance);         log.deBUG("remove successful");      }      catch (RuntimeException re) {        log.error("remove Failed",re);        throw re;      }    }    public SyDbVersion merge(SyDbVersion detachedInstance) {      log.deBUG("merging SyDbVersion instance");      try {         SyDbVersion result = entityManager.merge(detachedInstance);         log.deBUG("merge successful");         return result;      }      catch (RuntimeException re) {          log.error("merge Failed",re);          throw re;      }    }    public SyDbVersion findByID( long ID) {      log.deBUG("getting SyDbVersion instance with ID: " + ID);      try {          SyDbVersion instance = entityManager.find(SyDbVersion.class,ID);          log.deBUG("get successful");          return instance;      }      catch (RuntimeException re) {        log.error("get Failed",re);        throw re;      }    }  }  

SyDbVersionHome类是使用DB和Entity类中的Hibernate Tools生成的.

现在的问题是这条线:
  SyDbVersion instance = entityManager.find(SyDbVersion.class,ID);
每次当我从find方法返回时,会话都会关闭,因此懒惰的成员不再可用.

我正在考虑使用持久性单元名称正确配置PersistenceAnnotationBeanPostProcessor的方法,但是bean正在搜索JNDI中的持久性单元,我找不到为持久性单元注册JNDI条目的适当时间.

在生产中,因为我设置了持久性PersistenceAnnotationBeanPostProcessor,然后正确地共享EntityManager,并且每次查找后都不会关闭会话.

另一种解决方案是使用OpenEJB或embedded-glassfish在单元测试中模拟/拥有应用服务器(将成为集成测试).

我必须在d簧配置或代码中修改哪些选项以避免单元测试中出现此问题?

最佳答案我发现了我的代码问题.问题是当加载ApplicationContext然后我在一个Bean对象中缓存一些JPA实体.后来在测试方法中(在另一个事务中)我正在访问这个延迟加载关系.当然这不是设计工作,你必须在同一个事务上下文中访问加载延迟加载的关系,否则你会得到一个像我的情况一样的异常.

解:

>使用而不是LAZY装载,EAGER装载.
>在返回之前显式初始化所需的所有关联和集合.然后你也可以在另一个交易中访问它们.

节点n = // ..获取节点

状态,Hibernate.initialize(N); //初始化’parent’,类似于getParent.

状态,Hibernate.initialize(n.getChildren()); //将延迟集合传递给要初始化的会话.
>尝试保持会话/事务处于打开状态,直到您需要它为止.在我的情况下,这是不可能的,没有任何意义. 总结

以上是内存溢出为你收集整理的使用Hibernate配置Spring JPA应用程序进行单元测试(延迟加载)全部内容,希望文章能够帮你解决使用Hibernate配置Spring JPA应用程序进行单元测试(延迟加载)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1250810.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)