我正在尝试测试具有 EntityManager 依赖项的无状态 session bean。
这是我创建 EntityManager 的持久单元:
<persistence-unit name="ThunderstormTest-PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.robinfinch.thunderstorm.customer.Customer</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:haildb"/>
<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbc.JDBCDriver"/>
<property name="javax.persistence.jdbc.username" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="eclipselink.target-database" value="HSQL"/>
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
这是命名查询:
@NamedQuery(
name="findCustomerWithName",
query="select c from Customer c where c.name = :custName"
)
问题是,在保留客户之后,
em.find(Customer.class, id)
返回持久化客户,但是
em.createNamedQuery("findCustomerWithName")
.setParameter("custName", name)
.getResultList()
没有。
日志显示两个查询:
--Execute query ReadObjectQuery(name="readObject" referenceClass=Customer sql="SELECT ID, NAME FROM CUSTOMER WHERE (ID = ?)")
--Execute query ReadAllQuery(name="findCustomerWithName" referenceClass=Customer sql="SELECT ID, NAME FROM CUSTOMER WHERE (NAME = ?)")
当我使用 ProgreSQL 数据库时,一切都按预期运行。
任何关于正在发生的事情的想法将不胜感激。
最佳答案
em.find()
将使用缓存来查找实体,而查询则直接访问数据库。显然在这种情况下它们不同步。
我还注意到您使用 RESOURCE_LOCAL
作为事务类型。您确定要这样做吗?通常,当在 session bean 中使用 JPA 时,您需要将 JTA 作为事务类型,以便 JPA 事务与 EJB 事务同步。 (RESOURCE_LOCAL
通常适用于 Java SE 应用程序。)在这种情况下,您可以通过关闭缓存来避免刷新实体管理器的需要:
<property name="eclipselink.cache.shared.default" value="false"/>
关于unit-testing - 为什么使用内存数据库时此 NamedQuery 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9752841/