IllegalArgumentException:不是实体 - hibernate/jpa和Maven中的分布式模型定义

Pet*_*ete 2 hibernate jpa maven

我们正在开发一个使用Spring,Hibernate/JPA和Maven的Web应用程序.我们有几个模块定义了不同的实体,所有模块都基于定义数据访问的核心模块和在tomcat上作为战争部署的Web视图项目.

现在我在persistence.xml放置方面遇到了很多麻烦.实际上我根本不想使用它,因为我正在所有java/test/resources文件夹中存在的一些datasource.xml文件中进行所有hibernate(即jpa)设置以及实际的web项目.然而,无论如何,hibernate似乎都需要它,因为我不断得到它

...
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
Run Code Online (Sandbox Code Playgroud)

对于我所有的模特.(例如:)

@Entity
@Table(name="customer")
public class Customer extends AbstractPersistable<Long> {
Run Code Online (Sandbox Code Playgroud)

所以我的包的设置如下:

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)
Run Code Online (Sandbox Code Playgroud)

如果我将META-INF/persistence.xml放在main/resources中,一切都很好,这意味着maven将构建项目,运行hibernate将自动创建表的测试.但是,由于我有很多模块项目可以合并到我的网络应用程序中,我会得到一个

IllegalStateException: No single default persistence unit defined
Run Code Online (Sandbox Code Playgroud)

我的Web项目设置是

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
Run Code Online (Sandbox Code Playgroud)

所以它几乎是这里提到的第一个设置,应该没问题.

如果在我的"模型罐"中,我将META-INF/persistence.xml放在test/resources中,我得到上面提到的"非实体"异常.

那么......如果我想在我的"模块"罐中定义(和测试)实体对象并在我的"视图"战争中使用它们,我该如何设置我的项目?

谢谢你!

编辑: 找出原因

IllegalStateException: No single default persistence unit defined
Run Code Online (Sandbox Code Playgroud)

似乎,我需要在我的模型罐中命名所有持久性单元.然而,现在我的网络应用程序抱怨一个jar而另一个很好,而两个都有完全相同的设置.我只是无法摆脱"非实体"的例外.

编辑2:

奇怪的是,我现在有一个项目将构建和单元测试自己的模型但是当在web容器内部使用时会抱怨只有那些模型不是实体,而具有100%完全相同设置的第二个项目将工作得很好.让我觉得我的网络应用程序中有些东西是错的,但我看不出是什么.

有没有人经历过这个?我找不到适合我的设置或提出适用解决方案的谷歌有用的东西..

编辑3:

似乎是一个maven集成问题.在我的Webapp pom中,我有以下设置:

    <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>
Run Code Online (Sandbox Code Playgroud)

view-jsf提供了jsf特定的东西,在这里并不重要.

prototype包含一些原型模型(enitity)定义,包括管理器和提供者.

安全性包含安全模型定义,如帐户,角色等,以及仍然要实现的特定于spring-security的东西;)

原型和安全性也参考核心项目,这些核心项目反过来定义数据访问以及更多依赖性,如spring.

现在有趣的部分:如果在我的webapp pom中我在原型之前移动安全性,原型实体将加载正常,安全实体将抛出IllegalArgumentException并说"不是实体".如果我在安全性之前放置原型,原型实体将抛出异常.

因此,似乎maven覆盖了两个项目中相同的内容,因此只有第二个成功加载.将进一步调查......

编辑4: 进一步的调查表明,问题是在一个持久性单元中有多个jars定义JPA实体(例子).将打开一个新的问题并针对该问题并在此处发布链接,因为这个线程有点长而且令人困惑.

Pet*_*ete 6

这里将问题压缩成一个单独的帖子

当两个罐子里面有一个persistence.xml定义实体persistence-unit(显式或隐式)然后加载到一个战争(在我的情况下由maven)时,就会引发异常.

该解决方案似乎只在Web应用程序中只有一个persistence.xml并列出了所有实体(除了jar单元测试,其中必须在其资源中包含persistence.xml).

仍然想知道是否有更动态的解决方案......