we're working on a web app with Spring, Hibernate/JPA and Maven. We have several modules that define different entities all based on a core module defining data access and a web view project that gets deployed as a war on a tomcat.
Now I'm having quite a bit of trouble with that persistence.xml placement. Actually I don't want to use it at all, as I'm doing all my hibernate (that is the jpa) setup inside some datasource.xml files that are present in all java/test/resources folders as well as the actual web project. However hibernate seems to need it anyway, since I keep getting an
...
Caused by: java.lang.IllegalArgumentException: Not an entity: class ....model.Customer
at org.hibernate.ejb.metamodel.MetamodelImpl.entity(MetamodelImpl.java:160)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:58)
at org.springframework.data.jpa.repository.support.JpaPersistableEntityInformation.<init>(JpaPersistableEntityInformation.java:44)
at org.springframework.data.jpa.repository.utils.JpaClassUtils.getMetadata(JpaClassUtils.java:100)
at ...JpaProvider.init(JpaProvider.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:340)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:293)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:130)
... 58 more
for all my models. (e.g.:)
@Entity
@Table(name="customer")
public class Customer extends AbstractPersistable<Long> {
So the setup for my packages is as follows:
src/main/java - contains the model classes
src/main/resources - contains application context
src/test/java - contains unit tests
src/test/resources - contains test context and datasource (JPA setup)
if I place the META-INF/persistence.xml inside main/resources everything's fine, meaning maven will build the project, running tests where hibernate will automatically create the tables. However since I have many module projects that get combined inside my web app I will get a
IllegalStateException: No single default persistence unit defined
My Web project setup is
src/main/resources/META-INF - containing the persistence.xml being deployed to WEB-INF/classes
src/main/webapp/WEB-INF - containing web.xml, faces-config, application-context, ... being deployed to /
src/main/java - containing controller classes being deployed to WEB-INF/classes
so it's pretty much the first setup mentioned here and should be fine.
If in my "model jars" I place the META-INF/persistence.xml inside test/resources I get above mentioned "not an entity" exception.
So... How do I set up my projects if I want to define (and test) entity objects in my "module" jars and use them all in my "view" war?
Thank's a bunch!
edit: Figured out the cause for
IllegalStateException: No single default persistence unit defined
Seems, I need to name all persistence units the same in my model jars. Now however my web app complains about one jar while the other one is fine while both have the exact same setup. I just can't get rid of the "Not an entity" exception.
edit 2:
Weirdly enough, I now have a project that will build and unit test its own models but when used inside the web container will complain that just those models are not an entity while a second project with the 100% exact same setup will work just fine. Make me think there's something in my web app that's wrong but I just can't see what.
Did anyone ever experience this? I can't find anything useful at google that fits my setup or proposes an applicable solution..
edit 3:
Seems to be a maven integration problem. In my Webapp pom I have the following setup:
<dependency>
<groupId>...</groupId>
<artifactId>view-jsf</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>...</groupId>
<artifactId>prototype</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>...</groupId>
<artifactId>security</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
view-jsf provides jsf specific stuff and is not important here.
prototype contains some prototype model(enitity) definitions including managers and providers.
security contains security model definitions like account, role, etc. as well as spring-security specific stuff that is still to be implemented ;)
both prototype and security also reference core projects that in turn define data access as well as more dependencies like spring.
NOW for the fun part: if, in my webapp pom I move security before prototype, the prototype entities will load fine and the security entities will throw an IllegalArgumentException and say "Not an entity". If I put prototype before security, the prototype entities will throw the exception.
So it seems like maven overrides something that is the same in both projects so that only the second one gets loaded successfully. Will investigate further...
edit 4: Further investigation showed, that the problem is having multiple jars defining JPA entities inside one persistence unit (example). Will open up a new question and for that issue and post the link here, as this thread is getting a bit to long and confusing.