【问题标题】:How to mention persistenceUnitName when packagesToScan property如何在 packagesToScan 属性时提及 persistenceUnitName
【发布时间】:2013-09-23 19:54:51
【问题描述】:

我有两个数据源和两个 entityManagerFactory 实例。我正在尝试使用 3.1 的新功能(通过使用 packagesToScan 属性在没有 persistence.xml 的情况下引导 JPA entityManagerFactory)。

为了使用正确的实体管理器工厂实例,我必须区分使用持久性单元名称和在persistence.xml中定义PU名称是停止spring包扫描功能。

在使用 packagesToScan 功能时如何给出 PU 名称?

我的问题更重复Is there a way to give persistenceUnitName for Spring's LocalContainerEntityManagerFactoryBean without persistence.xml?

我找不到上述帖子的答案或评论。所以重新发布为新问题。

【问题讨论】:

    标签: java spring hibernate jpa


    【解决方案1】:

    是的,你可以。这是一个使用 Spring 的注解配置的示例

    我发现最好将每个数据源组织到不同的包中。
    我的包结构是:

    datasource
        |__ converters         <-- holds any custom attribute converters for JPA
        |__ default            <-- for default datasource
        |       |__ model      <-- contains entities for default datasource
        |       |__ repository <-- contains repositories for default datasource
        |__ anotherdatasource  <-- for second datasource
                |__ model      <-- contains entities for second datasource
                |__ repository <-- contains repositories for second datasource
    

    选择其中一个数据源作为默认数据源,并按照...为它创建一个配置类

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", basePackages = { "com.example.datasource.default.repository" })
    public class JpaDefaultDatasourceConfig {
    
        @Primary
        @Bean(name = "dataSource")
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource dataSource() {
            return DataSourceBuilder.create().build();
        }
    
        @Primary
        @Bean(name = "entityManagerFactory")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("dataSource") DataSource dataSource) {
            return builder.dataSource(dataSource).packages("com.example.datasource.default.model", "com.example.datasource.converters").persistenceUnit("mydefault").build();
        }
    
        @Primary
        @Bean(name = "transactionManager")
        public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
            return new JpaTransactionManager(entityManagerFactory);
        }
    }
    

    然后为每个后续数据源创建另一个配置类... 注意:使用包来分隔实体/存储库扫描和贯穿始终使用的命名约定)

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(entityManagerFactoryRef = "anotherEntityManagerFactory", transactionManagerRef = "anotherTransactionManager", basePackages = { "com.example.datasource.anotherdatasource.repository" })
    public class JpaAnotherDatasourceConfig {
    
        @Bean(name = "anotherDataSource")
        @ConfigurationProperties(prefix = "another.datasource")
        public DataSource anotherDataSource() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "anotherEntityManagerFactory")
        public LocalContainerEntityManagerFactoryBean anotherEntityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("anotherDataSource") DataSource anotherDataSource) {
            return builder.dataSource(anotherDataSource).packages("com.example.datasource.anotherdatasource.model", "com.example.datasource.converters").persistenceUnit("anotherName").build();
        }
    
        @Bean(name = "anotherTransactionManager")
        public PlatformTransactionManager anotherTransactionManager(@Qualifier("anotherEntityManagerFactory") EntityManagerFactory anotherEntityManagerFactory) {
            return new JpaTransactionManager(anotherEntityManagerFactory);
        }
    }
    

    您可以使用配置前缀配置每个数据源。对于上面的两个示例,您可以使用配置它们

    application.yml

    ## JPA configuration
    # This is the configuration for default datasource created by spring
    spring:
      datasource:
        url: jdbc:mysql://localhost/default
        username: foo
        password: bar
        driverClassName: com.mysql.jdbc.Driver
        test-on-borrow: true
        test-while-idle: true
        validation-query: select 1;
        # maxActive: 1
    
    # This is the configuration for an additional datasource which we will create ourselves
     another:
      datasource:
        url: jdbc:mysql://localhost/another
        username: foo
        password: bar
        driverClassName: com.mysql.jdbc.Driver
        test-on-borrow: true
        test-while-idle: true
        validation-query: select 1;
    

    您现在不必担心持久性单元的名称(尽管我们确实命名了它们),因为我们已经仔细分离了实体管理器,只查看它们的实体/存储库,您可以简单地注入适用的存储库和使用它而不必担心它会获取错误的数据源。如果您确实需要持久性单元,您可以直接按名称要求 @PersistenceUnit(name = "anotherDatasource")

    【讨论】:

      【解决方案2】:

      如果我正确理解您的问题,您想设置persistenceUnit 的名称支持EntityManagerFactory,但在没有persistence.xml 的情况下定义?

      当您声明 entityManagerFactory 时,您可以设置一个 persistenceUnitName 属性。例如:

      <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        <property name="dataSource" ref="dataSource"/>
      
        <property name="persistenceUnitName" value="yourPersistenceUnitName"/>
      
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
        <property name="packagesToScan">
          <list>
            <value>..</value>
            ...
          </list>
        </property>
      </bean>     
      

      【讨论】:

      • 我收到 IllegalArgumentException,它正在寻找带有 3.1 中定义的“yourPersistenceUnitName”的“persistence.xml”
      • 发布你的应用上下文
      猜你喜欢
      • 1970-01-01
      • 2014-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 2014-10-11
      相关资源
      最近更新 更多