Spring 从外部Jar文件加载JPA实体

Spring 从外部Jar文件加载JPA实体,spring,hibernate,jpa,Spring,Hibernate,Jpa,我有一个项目设置,其中我模块化了一个项目,并将一个模块打包到一个jar文件中,当我们创建一个war并部署它时,该文件将包含在主项目中。 我面临的问题是,模块中存在一个实体,当启动期间为unitName构建JPA容器EntityManagerFactory时,该实体不会加载 我的基本问题是,EntityManager是否在persistence.xml上查找,然后加载指定的属性,然后扫描所有包以查找@Entity注释 任何关于这是如何工作的以及我如何解决这一问题的见解都将是非常棒的 我找到了这个链

我有一个项目设置,其中我模块化了一个项目,并将一个模块打包到一个jar文件中,当我们创建一个war并部署它时,该文件将包含在主项目中。 我面临的问题是,模块中存在一个实体,当启动期间为unitName构建JPA容器EntityManagerFactory时,该实体不会加载

我的基本问题是,EntityManager是否在persistence.xml上查找,然后加载指定的属性,然后扫描所有包以查找@Entity注释

任何关于这是如何工作的以及我如何解决这一问题的见解都将是非常棒的

我找到了这个链接,它提到了创建独立的持久性单元,但这里我不需要一个独立的持久性单元。我只需要模块背驮父项目并加载实体和任何其他@Resource、@Component类,这是由于上下文:Component scan和annotation config

这是我的代码/配置

<bean id="entityManagerFactory"  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceUnitName" value="LineManagement" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="false" />
            <property name="showSql" value="false" />
            <property name="databasePlatform" ref="cpsHibernateDialectClassName" />
        </bean>
    </property>
    <property name="beanName" value="entityManager"></property>
</bean>
。。。。 }

注意:实体与父实体位于不同的包中,因为它本身是一个独立的模块

在主项目中精细加载的实体

package com.parent.line.entity;

import javax.persistence.Entity;

@Entity
@Table(name = "ACCOUNT")
@Cacheable(true)
public class Account
  implements LMLookupTypeEntityByDivision, Serializable, Comparable<Account> {
package com.parent.line.entity;
导入javax.persistence.Entity;
@实体
@表(name=“ACCOUNT”)
@可缓存(真)
公共类帐户
实现LMLookupTypeEntityByDivision、可序列化、可比较{

要扫描驻留在jar中的实体,必须将其包含在persistence.xml中。
packedEntity.jar

如果您想从包中加载单元,那么您可以尝试直接从jar注入它。
@PersistenceContext(unitName=“../packedEntity.jar#main”)

尚未尝试,但您可以启用实体的hibernate自动检测

在工作中,我们不使用JPA,而是使用Hibernate,我们的项目是完全模块化的。 我们处理大约30个不使用相同模块的国家,我们可以通过简单地更改maven依赖项(无需修改orm文件)在会话工厂中加载所有这些模块的实体

使用的解决方案是使用JavaSPI。 ServiceLoader将查找实现核心接口EntityProvider的类。 调用ServiceLoader.load(EntityProvider.class)时,每个模块的每个EntityProvider都将对其带来的实体进行硬编码,并返回一个实体列表。 因此,在平台核心中,我们只需要创建一个基于spring的会话工厂,在该工厂中,我们通过一个工厂bean提供实体列表,该工厂bean将调用SPI

我不知道使用JPA是否容易,但我非常确定这是可能的,但您可能需要从spring上下文手动创建EMF,我猜还需要PersistenceUnit…您可能需要的是一个持久性单元,它是所有模块(至少对于您的实体)的持久性单元的“合并” 看看SPI和javax.persistence.SPI包

还要检查如何使用Spring创建EMF: AbstractEntityManagerFactoryBean


编辑:您可以选中此项:

如果您正在使用springboot,请在主springboot类中使用实体扫描注释

@EntityScan(
        basePackageClasses = {externalpackage.classname.class}
)
简单使用

@EntityScan("com...pakage-which-contains-entities...")
或者,如果您有多个实体包,请使用

@EntityScan(basePackages = {"...pkg1...", "...pkg2..."} )

问题是因为我将模块作为依赖项添加到父项目中,因为它是完全分离的。因此它将被放置在我的WEB-INF/lib文件夹中。在调试加载实体的JPA代码后,我意识到它开始扫描@Entity注释的类路径来自WEB-INF/classes。这使得ense,因为lib是只读的。现在,我必须考虑在classes文件夹中添加模块,或者以某种方式使用persistence.xml中的标记,以便扫描和加载jar实体
@EntityScan("com...pakage-which-contains-entities...")
@EntityScan(basePackages = {"...pkg1...", "...pkg2..."} )