我的jar文件中有一个空的persistenceUnit:
<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 :(得分: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-processes期间“过滤”并替换字符串 那么你将在配置文件中定义属性。 https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
您还可以将基本persistence.xml作为默认文件添加到项目中。因此,如果没有激活maven-profile,将使用这个。 (即使可能发生,如果未正确配置数据资源,应用程序也无法按预期工作)
答案 1 :(得分:0)
Spring提供了一个接口JpaVendorAdapter,它允许在应用程序启动期间通过Spring Java配置或XML配置插入任何JPA供应商特定的配置。
您可以使用LocalContainerEntityManagerFactoryBean和JpaVendorAdapter的任何实现类创建EntityManagerFactory实例,例如HibernateJpaVendorAdapter,EclipseLinkJpaVendorAdapter或OpenJpaVendorAdapter。
我相信如果你的应用程序使用Spring,你甚至不需要在persistence.xml中定义空的持久性单元。
以下是有关如何使用Spring Java config创建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的内容的其他信息,请参阅以下URL: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html
答案 2 :(得分:0)
我假设您要在超类中声明持久单元,并且希望在显式项目中定义持久单元。如果是,你可以使用这样的JNDI approch:
<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;