В проекте EE6 / CDI / JPA тест src/test/resources/META-INF/persistence.xml
выполняется без каких-либо дополнительных настроек.
При использовании JPA в Spring в контексте приложения, используемого для тестирования, работает следующее:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--
JPA requires META-INF/persistence.xml, but somehow prefers the one
in classes/META-INF over the one in test-classes/META-INF. Spring
to the rescue, as it allows for setting things differently, like by
referring to "classpath:persistence-TEST.xml". Or, simply referring
to "META-INF/persistence.xml" makes JPA use the test version too:
-->
<property name="persistenceXmlLocation" value="META-INF/persistence.xml" />
<!-- As defined in /src/test/resources/META-INF/persistence.xml -->
<property name="persistenceUnitName" value="myTestPersistenceUnit" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
</bean>
</property>
</bean>
Здесь /src/test/resources/META-INF/persistence.xml
(копируется в target/test-classes
) предпочтительнее, чем /src/main/resources/META-INF/persistence.xml
(копируется в target/classes
).
К сожалению, местоположение файла persistence.xml
также определяет так называемый " корень единицы сохраняемости ", который затем определяет, какие классы сканируются для аннотаций @Entity
. Таким образом, использование /src/test/resources/META-INF/persistence.xml
будет сканировать классы в target/test-classes
, а не классы в target/classes
(где будут жить классы, которые необходимо протестировать).
Следовательно, для тестирования необходимо явно добавить <class>
записей в persistence.xml
, чтобы избежать java.lang.IllegalArgumentException: Not an entity: class ...
. Необходимость в записях <class>
можно избежать, используя другое имя файла, например persistence-TEST.xml
, и поместите этот файл в ту же папку, что и обычный файл persistence.xml
. Тогда контекст Spring из вашей тестовой папки может просто ссылаться на <property name="persistenceXmlLocation" value="META-INF/persistence-TEST.xml" />
, и Spring найдет его для вас в src/main
.
В качестве альтернативы можно сохранить persistence.xml
одинаковым для реального приложения и тестов и определить только один в src/main
. Вместо этого большинство настроек, таких как драйверы, диалект и дополнительные учетные данные, можно выполнить в контексте Spring. Также такие параметры, как hibernate.hbm2ddl.auto
могут быть переданы в контексте :
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- For example: com.mysql.jdbc.Driver or org.h2.Driver -->
<property name="driverClassName" value="#{myConfig['db.driver']}" />
<!-- For example: jdbc:mysql://localhost:3306/myDbName or
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 -->
<property name="url" value="#{myConfig['db.url']}" />
<!-- Ignored for H2 -->
<property name="username" value="#{myConfig['db.username']}" />
<property name="password" value="#{myConfig['db.password']}" />
</bean>
<bean id="jpaAdaptor"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- For example: org.hibernate.dialect.MySQL5Dialect or
org.hibernate.dialect.H2Dialect -->
<property name="databasePlatform" value="#{myConfig['db.dialect']}" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="jpaProperties">
<props>
<!-- For example: validate, update, create or create-drop -->
<prop key="hibernate.hbm2ddl.auto">#{myConfig['db.ddl']}</prop>
<prop key="hibernate.show_sql">#{myConfig['db.showSql']}</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>