2017-03-07 172 views
0

我在jar文件中有一个空的persistenceUnit:重写JPA持久性单元

<persistence-unit transaction-type="JTA" name="base1"> 
    </persistence-unit> 

    <persistence-unit transaction-type="JTA" name="base2"> 
    </persistence-unit> 

我的想法是,在我的主要项目属性和类全persistenceUnit更换空persistenceUnit,像这样:

<persistence-unit name="base1" transaction-type="JTA"> 
     <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
     <jta-data-source>java:jboss/datasources/myDS</jta-data-source> 
     <class>br.com.myproject.MyClass</class> 
     <exclude-unlisted-classes>true</exclude-unlisted-classes> 
     <shared-cache-mode>NONE</shared-cache-mode> 
     <properties> 
      <property name="hibernate.hbm2ddl.auto" value="none" /> 
      <property name="hibernate.show_sql" value="true" /> 
      <property name="hibernate.format_sql" value="false" /> 
      <property name="hibernate.cache.use_second_level_cache" 
         value="false" /> 
     </properties> 
    </persistence-unit> 

但是,当我尝试启动服务器,我得到了以下错误:

Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYJPA0038: Falha ao adicionar o serviço da unidade de persistência para base1 
    Caused by: org.jboss.msc.service.DuplicateServiceException: Service jboss.persistenceunit.myproject#base1.__FIRST_PHASE__ is already registered"}} 

是否有任何方法来重写persistenceUnit?

+0

是存在的,为什么你打上一个原因JTA,看起来像资源作为非-jta数据源? – The86Freak

+0

不,这只是一个错误,我会编辑我的文章。 – RonaldoLanhellas

+0

你的包装做得对吗?在JAR/WAR等中没有重复的persistence.xml? 我也建议删除不需要的PU,如“base2”。 – The86Freak

回答

0

如果您确实需要动态覆盖persistence.xml,那么在构建过程中最好做到这一点。

我的个人警告:这听起来像是一个配置 - 对我来说,我宁愿建议在这里使用容器管理的JNDI方法。

但无论如何: 使用2个maven配置文件。 如果您激活profile1,则来自profile1的persistence.xml将被添加到正确的位置。并且如果您激活profile2,则将从profile2启用persistence.xml。

因此使用copy-resources-mojo作为maven。 https://maven.apache.org/plugins/maven-resources-plugin/examples/copy-resources.html

如果参数仅仅是值的变化,而不是整个结构, 那么你也可以只是“过滤器”并更换期间Maven的过程中串 那么就需要定义的配置文件的属性。 https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html

您还可以添加一个基本的persistence.xml到您的项目作为默认文件。因此,如果没有maven配置文件被激活,这个将被使用。 (即使可能发生,如果数据资源配置不正确,应用程序无法正常工作)

0

Spring提供了一个接口JpaVendorAdapter,它允许通过Spring Java配置插入任何JPA供应商特定配置或在应用程序启动期间的XML配置

您可以使用LocalContainerEntityManagerFactoryBean和JpaVendorAdapter的任何实现类(如HibernateJpaVendorAdapter,EclipseLinkJpaVendorAdapter或OpenJpaVendorAdapter)创建一个EntityManagerFactory实例。

我相信你甚至不需要在persistence.xml中定义空的持久化单元,如果你的应用程序使用了Spring。

下面是关于如何使用的Spring Java配置创建EntityManagerFactory的示例:

@Inject 
    private DataSource base1DataSource; 

    @Inject 
    private DataSource base2DataSource; 

    @Bean 
    public EntityManagerFactory base1EntityManagerFactory() 
      throws IOException, NamingException { 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 

     LocalContainerEntityManagerFactoryBean containerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
     containerEntityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter); 
     containerEntityManagerFactoryBean.setPackagesToScan("YOUR_PACKAGE_NAMES"); 
     containerEntityManagerFactoryBean.setJtaDataSource(base1DataSource); 
     containerEntityManagerFactoryBean.setJpaProperties(loadBase1JpaProperties()); 
     containerEntityManagerFactoryBean.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE); 
     containerEntityManagerFactoryBean.setPersistenceUnitName("base1"); 
     containerEntityManagerFactoryBean.afterPropertiesSet(); 

     return containerEntityManagerFactoryBean.getObject(); 
    } 

    @Bean 
    public EntityManagerFactory base2EntityManagerFactory() 
      throws IOException, NamingException { 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 

     LocalContainerEntityManagerFactoryBean containerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
     containerEntityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter); 
     containerEntityManagerFactoryBean.setPackagesToScan("YOUR_PACKAGE_NAMES"); 
     containerEntityManagerFactoryBean.setJtaDataSource(base2DataSource); 
     containerEntityManagerFactoryBean.setJpaProperties(loadBase2JpaProperties()); 
     containerEntityManagerFactoryBean.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE); 
     containerEntityManagerFactoryBean.setPersistenceUnitName("base2"); 
     containerEntityManagerFactoryBean.afterPropertiesSet(); 

     return containerEntityManagerFactoryBean.getObject(); 
    } 

    @Bean 
    public Properties loadBase1JpaProperties() throws IOException { 
     ClassPathResource resource = new ClassPathResource("base1-persistence.properties"); 

     return PropertiesLoaderUtils.loadProperties(resource); 
    } 

    @Bean 
    public Properties loadBase2JpaProperties() throws IOException { 
     ClassPathResource resource = new ClassPathResource("base2-persistence.properties"); 

     return PropertiesLoaderUtils.loadProperties(resource); 
    } 

请参阅以下网址,了解更多信息您可以覆盖到你的persistence.xml什么: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html

0

我假设你想要在超类中声明持久单元,并且你想要在一个明确的项目中定义持久单元。如果属实,你可以使用JNDI计算策略是这样的:

<persistence-unit name="MyPersistenceUnit" 
    transaction-type="JTA"> 

    <jta-data-source>java:/myDS</jta-data-source> 

    <mapping-file>META-INF/orm.xml</mapping-file> 


    <jar-file>Persistence.jar</jar-file> 

    <properties> 

     <property name="jboss.entity.manager.jndi.name" value="java:app/applicationEntitymanager"/> 
     <!-- Properties for Hibernate --> 
     <property name="hibernate.hbm2ddl.auto" value="update" /> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> 
     <property name="hibernate.show_sql" value="false" /> 
    </properties> 

</persistence-unit> 

的另一边,你可以与存取权限了EntityManager:

@Resource(mappedName = "java:app/applicationEntitymanager") 
protected EntityManager em;