there's a LOT of questions on this on the internets.. however I still struggle with what seems to be a quite typical scenario.
I'm doing a quite simple JPA (using Hibernate) project, with Entity classes being resided with a com.actions.domain
package
I have persistence.xml
as follows:
<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>
this file resides in src\test\resources\META-INF
folder
I have also JUnit test classes written like this:
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();
}
An example of an Entity:
@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;
}
}
If I put a <class>com.actions.domain.Action</class>
element into persistence unit description, it all works like a charm, however I don't want to enumerate the classes here by hand, also don't want to have any hibernate.cfg.xml
file
So if I remove that element, and try to somehow have provider auto-scan for entities, I get errors like Unknown entity: com.actions.domain.Action
I've tried running these tests both a Run configuration in IntelliJ and as a gradle test
command. In none of the cases META-INF folder is in the same directory as classes
, so how are people achieving this ??
How on Earth can one have it working ?
UPDATE: there's an accepted answer to identical question here: https://stackoverflow.com/a/16598682/2583044 Still, I'm struggling to believe that such a main-stream use case issue could have such a marginal dirty hack of a solution :(
The issue was resolved (thanks to Vlad Mihalcea) ultimately as follows:
META-INF
folder under src/main
Added the following to build.gradle
:
apply plugin: 'idea'
idea { module { inheritOutputDirs = true } }
sourceSets { main { output.resourcesDir = "build/classes" } test { output.resourcesDir = "build/classes" } }
Afterwards, tests are working as expected both from IDEA and with Gradle.