есть МНОГО вопросов по этому поводу в Интернете ... однако я все еще борюсь с тем, что кажется довольно типичным сценарием.
Я делаю довольно простой проект JPA (с использованием Hibernate), где классы Entity находятся в пакете com.actions.domain
.
У меня persistence.xml
такой:
<persistence xmlns = "http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version = "2.1">
<persistence-unit name = "my-persistence-unit">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name = "javax.persistence.jdbc.driver"
value = "org.h2.Driver" />
<property name = "javax.persistence.jdbc.url"
value = "jdbc:h2:~/test.h2db" />
<property name = "hibernate.archive.autodetection" value = "class, hbm"/>
</properties>
</persistence-unit>
</persistence>
этот файл находится в папке src\test\resources\META-INF
У меня также есть тестовые классы JUnit, написанные так:
protected EntityManager entityManager;
@Before
public void setUp() throws Exception {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("my-persistence-unit");
entityManager = entityManagerFactory.createEntityManager();
}
@Test
public void actionsAdded_success() {
entityManager.getTransaction().begin();
entityManager.persist(new Action("TEST_ACTION1", "ACTION"));
entityManager.persist(new Action("TEST_ACTION2", "ACTION"));
entityManager.getTransaction().commit();
}
Пример сущности:
@Entity
@Table(name = "UC_ACTIONS")
@Data
public class Action {
@Id
@GeneratedValue(generator = "increment")
private Long id;
private String name;
private String type;
public Action(String name, String type) {
this.name = name;
this.type = type;
}
}
Если я помещу элемент <class>com.actions.domain.Action</class>
в описание блока сохранения состояния, все будет работать как шарм, однако я не хочу перечислять здесь классы вручную, а также не хочу иметь никаких файлов hibernate.cfg.xml
.
Поэтому, если я удалю этот элемент и попытаюсь каким-то образом включить автоматическое сканирование провайдером сущностей, я получу такие ошибки, как Unknown entity: com.actions.domain.Action
.
Я пробовал запускать эти тесты как в конфигурации «Выполнить» в IntelliJ, так и в качестве команды gradle test
. Ни в одном из случаев папка META-INF не находится в том же каталоге, что и classes
, так как же люди этого добиваются?
Как вообще можно заставить это работать?
ОБНОВЛЕНИЕ: здесь есть принятый ответ на идентичный вопрос: https://stackoverflow.com/a/16598682/2583044 Тем не менее, я изо всех сил пытаюсь поверить, что такая проблема с основным вариантом использования может иметь такой маргинальный грязный взлом решения :(
Когда вы задаете вопрос, напишите, какой инструмент сборки вы используете.
"и как тестовая команда gradle". ... в тот момент мне пришлось быть более конкретным, трудно ожидать, что отвечающий прочитает весь вопрос
По умолчанию автоопределение работает для сущностей в том же элементе пути к классам, что и persistence.xml. Его можно настраивать по элементам.
Чтобы включить правильное автоматическое определение, когда файл persistence.xml находится в src / test / resources / META-INF, я использую следующий трюк:
persistence.xml
<persistence ...>
<persistence-unit ...>
<jar-file>${project.build.outputDirectory}</jar-file>
...
</persistence-unit>
</persistence>
pom.xml - включить фильтрацию ресурсов для src / test / resources:
<project ...>
...
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>
</project>
да ... трюк в том, что я использую Gradle ... но все равно спасибо за предложение!
Ваше предложение актуально, но, к сожалению, оно использует Maven, поэтому формально я не могу его принять ((
Проблема была решена (спасибо Влад Михалча) в конечном итоге следующим образом:
META-INF
перенесена в папку src/main
.В build.gradle
добавлено следующее:
применить плагин: 'идея'
idea { module { inheritOutputDirs = истина } }
sourceSets { главный { output.resourcesDir = "сборка / классы" } тестовое задание { output.resourcesDir = "сборка / классы" } }
После этого тесты работают, как ожидалось, как от IDEA, так и с Gradle.
<exclude-unlisted-classes>false</exclude-unlisted-classes>