我正在开发一个实现spring + hibernate entitymanager
的基本webapp我完全按照这篇文章的描述设置我的dao和上下文: http://blog.springsource.com/2006/08/07/using-jpa-in-spring-without-referencing-spring/
并为其创建了一个测试,如下所示: http://lstierneyltd.com/blog/development/examples/unit-testing-spring-apps-with-runwithspringjunit4classrunner-class/
出于某种原因,当我尝试访问entitymanager来创建查询时,它的null。
但是,通过在entitymanager的setter方法中设置断点,我可以看到Spring正确地注入它,并且字段正在初始化。
有关为什么在setter返回后实体管理器可能会被取消的任何线索?
编辑: 我设置断点的dao代码:
public class ProductDaoImpl implements ProductDao {
private EntityManager entityManager;
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this. entityManager = entityManager;
}
public Collection loadProductsByCategory(String category) {
return entityManager.createQuery("from Product p where p.category = :category")
.setParameter("category", category).getResultList();
}
}
答案 0 :(得分:0)
我认为你拥有的<tx:annotation-driven/>
告诉Spring将事务建议放在任何有@Transactional
注释的类或方法上。
应在服务/业务层定义交易,因此通常在服务中调用ProductDaoImpl
,将拥有@Transactional
。 e.g。
pubic class ProductService {
@Resource(...) // inject it the way you like e.g. @Autowired / Setter / Constructor injection, etc..
ProductDao yourProductDao;
@Transactional
public List<Product> findCarProducts {
yourProductDao.loadProductsByCategory( "car" );
}
}
(或者,您可以使用基于XML的事务配置)
现在,您对DAO的实际调用将是within
一次交易=&gt;这对于entityManager / Hibernate Session非常重要。否则,您会看到所有常见错误:例如entityManager为null,entityManager关闭等。
如果您想单独测试DAO,则必须确保您的测试用例通过@TransactionConfiguration
包含在事务中。例如,如果您的事务管理器bean定义为:
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
您的DAO测试将包含此bean名称:
@ContextConfiguration
@TransactionConfiguration(transactionManager="txManager", defaultRollback=false)
public class ProductDaoTransactionalTests {
// your use cases here..
}
中详细了解交易测试