ОК, извините, я искал ответы на эти вопросы часами, но мне потребовалось ввести весь вопрос для StackOverflow, чтобы всплыть нужная ссылка. Вы можете прочитать много соответствующей информации здесь .
У меня есть проект Spring, созданный с помощью Spring Roo для использования Hibernate и MySQL. Однако для тестирования я хочу использовать HSQLDB в памяти, потому что тесты интеграции Roo удаляют данные с идентификаторами (первичными ключами) от 0 до 10 (вместо того, чтобы удалять данные с помощью назначенных для базы данных идентификаторов для данных, которые они уже создали), что означает, что это удаляет данные, которые уже находятся в базе данных, что в моем случае приводит к нарушению ограничения, прежде чем происходит откат транзакции.
Это немного сложнее, потому что я переключаю целые провайдеры баз данных, что означает разные диалекты Hibernate, а также разные настройки DDL (проверка в процессе производства, проверка на создание-падение). Но это не работает так, как я ожидал, и я озадачен, почему.
Если вы знаете, почему это не работает, скажите, пожалуйста, даже если у вас нет решения.
Это проект Roo, я, конечно, использую Maven. Итак, первое, что я попробовал, было наличие файла src/test/resources/META-INF/persistence.xml
для конкретного теста, а также файла src/test/resources/META-INF/spring/database.properties
для конкретного теста. Это не сработало, как когда я запустил mvn test
все сломалось, с соответствующим сообщением было
Conflicting persistence unit definitions for name 'persistenceUnit'
Почему mvn test
все еще собирает не тестовые ресурсы?
Итак, я переименовал src/test/resources/META-INF/spring
в spring-test
и скопировал applicationContext.xml
в него. Я изменил конфигурацию контекста в тестовых классах на
@ContextConfiguration(locations = "classpath:/META-INF/spring-test/applicationContext*.xml")
Завершая (или я так думал) разделение, я сделал пару правок для spring-test/applicationContext.xml
:
Изменен путь к файлам свойств:
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
до
<context:property-placeholder location="classpath*:META-INF/spring-test/*.properties"/>
Изменено название персистентного юнита:
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
</bean>
до
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="testPersistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
</bean>
И я сделал соответствующее изменение имени единицы персистентности на src/test/resources/META-INF/persistence.xml
Хорошо, хорошо, теперь нет никакого конфликта, но каким-то образом Hibernate потерял сопоставления сущностей (например, для сущности Product
), и я получаю:
org.springframework.dao.InvalidDataAccessApiUsageException:
org.hibernate.hql.ast.QuerySyntaxException: Product is not mapped [SELECT o FROM Product o];
Почему Spring / Hibernate потерял сопоставления сущностей в этой конфигурации?
Итак, следующее, что я попробовал, - это объединение двух файлов persistence.xml
, чтобы один файл в src/main/resources/META-INF
включал в себя оба постоянных элемента.
Это работает !! ??
Я думаю, что это ужасно, потому что теперь у меня есть тестовая конфигурация в моем производственном коде, но это то, с чем я справляюсь.
Какой способ лучше?
Насколько я понимаю, свойства не доступны в файле persistence.xml, как в файлах Spring XML. Поэтому я не думаю, что смогу делать то, что хочу, только с помощью файла свойств для конкретного теста.
В идеале я бы запускал тесты, используя всю конфигурацию в src / main / resources, за исключением того, что специально переопределено в src / test / resources. Есть ли способ сделать это?
Спасибо за любую информацию, которую вы можете предоставить!