有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在webapp上下文中导入时,jar文件中配置的java PersistenceUnit具有错误的PersistenceUnitRootLocation URL

我使用的是Spring引导数据JPA和Tomcat启动器

我有一个应用程序,在几个maven模块中定义了多个持久化单元,这些模块在单独使用时工作正常:

Project
-- IdentityAccess [PU name: identity-access]
|--- src/main/java
      |--- myapp.application [Application services using "identityAccessTransactionManager"]
      |--- myapp.domain.model [Entites classes]
      |--- myapp.infrastructure.persistence [Repositories Impl using nested DataJpa repositories]
|--- src/main/resources
      |--- myapp/application.properties
      |--- myapp/hibernate.cfg.xml
      |--- myapp/infrastructure/persistence/Group.hbm.xml
      |--- myapp/infrastructure/persistence/GroupMember.hbm.xml
      |--- myapp/infrastructure/persistence/User.hbm.xml

-- Promotion [PU name: promotion]
...

-- WebApplication [There is no PU here]
-> Depends on IdentityAccess, Promotion

@SpringBootApplication
@Import({IdentityAccessContext.class, PromotionContext.class})

下面是我如何在每个PU中配置EntityManagerFactoryBean,并给它们一个唯一的bean名称以避免冲突注意:以下配置是每个模块中包含的一个类

@Configuration
@ComponentScan
@EnableJpaRepositories(
        transactionManagerRef = TRANSACTION_MANAGER,
        entityManagerFactoryRef = ENTITY_MANAGER_FACTORY,
        considerNestedRepositories = true)
public class IdentityAccessPersistenceConfiguration {
    public static final String PERSISTENCE_CONTEXT = "identity-access";
    public static final String ENTITY_MANAGER_FACTORY = "identityAccessEntityManagerFactory";
    public static final String TRANSACTION_MANAGER = "identityAccessTransactionManager";

    @Bean
    public LocalContainerEntityManagerFactoryBean identityAccessEntityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setDataSource(dataSource);
        entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter);
        entityManagerFactory.setMappingResources("myapp/identityaccess/hibernate.cfg.xml");
        entityManagerFactory.setPersistenceUnitName("identity-access");
        return entityManagerFactory;
    }

    @Bean
    public PlatformTransactionManager identityAccessTransactionManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }

}

当我单独启动每个模块时,即在测试上下文中,但也作为独立应用程序启动时,Entite被正确加载和映射,PersistenceUnitInfo描述符具有如下根URL:

file:/F:/Workspaces/myapp/IdentityAccess/target/classes/

但当我启动web应用程序时,每个PU都会附带另一个根URL,这是web应用程序上下文的根,因此它无法加载映射类:

file:/F:/Workspaces/myapp/WebApplication/target/WebApplication-1.0.0-SNAPSHOT/WEB-INF/classes/

它不应该是装有PU的罐子吗?我试图钩住setPersistenceUnitRootLocation来放置我的jar URL,但是我被卡住了,因为版本和路径可能会发生明显的变化。我甚至不知道这是一个bug还是我正在做一些不受支持的事情。也许这个bug甚至不属于Spring Boot,而是Spring本身

我觉得我接触了太多的内部构件,这就是为什么我认为这是一个bug,但如果不是,请纠正我,我已经在spring boot github上打开了一张具有相同描述的罚单

我还研究了: -https://github.com/spring-projects/spring-boot/issues/6983 -https://github.com/spring-projects/spring-boot/issues/6635 -https://github.com/spring-projects/spring-boot/issues/7003 -https://github.com/spring-projects/spring-boot/issues/7021

这似乎是相关的

谢谢你抽出时间


共 (1) 个答案

  1. # 1 楼答案

    我解决了这个问题:

    在组织中。springframework。靴子自动配置。奥姆。jpa。在JpaBaseConfiguration中,该方法假定持久化单元位于应用程序本身中:

    private URL determinePersistenceUnitRootLocation() {
            Class<?> source = getClass();
            try {
                URL url = source.getProtectionDomain().getCodeSource().getLocation();
                return ResourceUtils.extractJarFileURL(url);
            }
            catch (Exception ex) {
                logger.info("Could not determine persistence " + "unit root location from "
                        + source + " : " + ex);
            }
            return null;
        }
    

    源属于主webapp,因此类加载器放置了错误的路径文件

    要解决我的问题,需要使用jar中的配置类在配置文件中使用相同的方法设置RootPersistenceUnitRootLocation,并且该单元已从jar中正确加载

    问题是:SpringBootAutoConfigure应该使用持久化单元中的类,还是可以使用setJarUrl来包含适当的修复?还是只支持一个主持久性单元是一个坚定的选择?我认为自动配置并允许开箱即用的多个持久性单元(来自不同的JAR)将是非常好的,特别是对于域驱动的设计架构