Почему этот NamedQuery не работает при использовании БД в памяти? - PullRequest
2 голосов
/ 17 марта 2012

Я пытаюсь протестировать сессионный компонент без сохранения состояния с зависимостью EntityManager.

Это единица сохранения, с которой я создаю 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 Ответ

2 голосов
/ 17 марта 2012

Вам необходимо очистить менеджер сущностей .

em.find() будет использовать кеш для поиска сущности, тогда как запрос направляется прямо в базу данных.Очевидно, что в этом случае они не синхронизированы.

Я также заметил, что вы используете RESOURCE_LOCAL в качестве типа транзакции.Вы уверены, что хотите это сделать?Как правило, при использовании JPA в сессионных компонентах вы хотите JTA в качестве типа транзакции, чтобы транзакции JPA синхронизировались с транзакциями EJB.(RESOURCE_LOCAL обычно для приложений Java SE.) В этом случае вы можете обойти необходимость очистки менеджера сущностей, отключив кэш:

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