I've been trying to refactor a java project, moving submodules into separate projects deployed to our internal maven repository (archiva).
The classes from the submodules are the following:
org.example.srv.DomainUser
org.example.srv.DomainUserBean //entity manager
org.example.srv.UserGroup
org.example.srv.UserGroupBean //entity manager
It works fine when the source files are copied into the appropriate package folder inside of the main backend server project, but when we remove the source files from the backend server project and pull the same code in as a maven dependency, I get the following error upon attempting to access the database:
org.hibernate.UnknownEntityTypeException: Unable to locate persister: org.example.srv.DomainUser
Persistence XML for backend server project:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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">
<persistence-unit name="loginserver">
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
</properties>
</persistence-unit>
</persistence>
I can only imagine that it is something to do with the bean discovery when the projects are separate, but I'm really perplexed and it would be great to separate these projects with minimal configuration overhead.
Main server project pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example.srv</groupId>
<artifactId>loginserver</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>authobjects</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<finalName>loginserver</finalName>
</build>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
</project>
Auth Objects pom.xml (this project also contains ORM code for the classes, including JPQL statement builders, etc.):
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<pj.gid>org.example</pj.gid>
<pj.aid>authobjects</pj.aid>
<pj.ver>1.0.2-SNAPSHOT</pj.ver>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<groupId>${pj.gid}</groupId>
<artifactId>${pj.aid}</artifactId>
<version>${pj.ver}</version>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ent.tnp.utils</groupId>
<artifactId>genericentityejb</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-webdav</artifactId>
<version>1.0-beta-2</version>
</extension>
</extensions>
</build>
<distributionManagement>
<repository>
<id>internal</id>
<url>http://archiva.tnp.in/repository/internal/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://archiva.tnp.in/repository/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>internal</id>
<name>Archiva Managed Internal Repository</name>
<url>http://archiva.tnp.in/repository/internal/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>snapshots</id>
<name>Archiva Managed Snapshot Repository</name>
<url>http://archiva.tnp.in/repository/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>internal</id>
<name>Archiva Managed Internal Repository</name>
<url>http://archiva.tnp.in/repository/internal/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>snapshots</id>
<name>Archiva Managed Snapshot Repository</name>
<url>http://archiva.tnp.in/repository/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
Clarification: genericentityejb is an abstract class designed to compose JPQL queries and manage database queries for a JPA entity. The authobjects project extends it once for each of the entities it contains in order to provide persistence for each of those entities.
From what I see there are at least 4 modules involved:
org.example.srv:loginserver:0.0.2-SNAPSHOT
org.example:authobjects:1.0.0
org.example:authobjects:1.0.2-SNAPSHOT
ent.tnp.utils:genericentityejb:1.0.0
and I note some possible criticality:
loginserver
is not depending on authobjects
, but on genericentityejb
(are they two unrelated example projects?).loginserver
is not depending on authobjects:1.0.2-SNAPSHOT
, but on authobjects:1.0.0
loginserver
is not declaring any repository (neither a parent POM), so genericentityejb
is always resolved from your local machine repository, unlesssettings.xml
(that's OK).authobjects
project groupId, artifactId and version. Maybe it's not related, but I'd avoid such declaration.That being said, I'm using a similar structure for my projects, deploying to Wildfly 10.1, and Hibernate correctly discovers all entities in all dependencies.
So I'd try a clean round.
I'll ignore authobjects
since it's not referenced and I suppose required entity classes are in genericentityejb
:
genericentityejb
POM version to 1.0.1-SNAPSHOT
genericentityejb
folder: mvn clean install
authobjects
POM version to 1.0.3-SNAPSHOT
and dependency genericentityejb
to 1.0.1-SNAPSHOT
authobjects
folder: mvn clean install
loginserver
dependency authobjects
to 0.0.3-SNAPSHOT
and dependency authobjects
to 1.0.3-SNAPSHOT
loginserver
folder: mvn dependency:analyze
to check for used undeclared deps (maybe genericentityejb
?)loginserver
folder: mvn clean package
loginserver/target/loginserver-0.0.3-SNAPSHOT.war!/WEB-INF/lib/genericentityejb-1.0.3-SNAPSHOT.jar
and loginserver/target/loginserver-0.0.3-SNAPSHOT.war!/WEB-INF/lib/authobjects-0.0.3-SNAPSHOT.jar
are present and contain all the entity classes.Also it could be useful to look at the loginserver
effective POM
declaring repositories in pom.xml
or settings.xml
is a personal choice. Both approaches have pros and cons:
copy'n'paste repositories
edit a repo URL
when you release an artifact:
You can add <jar-file>
element, containing path to the jar
with entity clases, to the persistence.xml
or describe all entity classes using <class>
element.
Also, you can add entity classes programmatically using some package scanning approach. I have collected useful links and libraries for such approach here:
https://github.com/v-ladynev/hibernate-scanners-test
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With