为什么在使用内存数据库时,这个NamedQuery不起作用?

时间:2012-03-17 18:59:43

标签: unit-testing java-ee jpa hsqldb

我正在尝试使用EntityManager依赖项测试无状态会话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:

@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数据库时,一切都按预期工作。

对于正在发生的事情的任何想法都将非常感激。

1 个答案:

答案 0 :(得分:2)

您需要flush the entity manager

em.find()将使用缓存查找实体,而查询将直接进入数据库。显然,在这种情况下,它们不同步。

我还注意到您使用RESOURCE_LOCAL作为交易类型。你确定要这么做吗?通常,在会话bean中使用JPA时,您需要JTA作为事务类型,以便JPA事务与EJB事务同步。 (RESOURCE_LOCAL通常用于Java SE应用程序。)在这种情况下,您可以通过关闭缓存来满足刷新实体管理器的需要:

<property name="eclipselink.cache.shared.default" value="false"/>