spring - 将 OneToOne/ManyToOne 与 JPA 和多个数据源一起使用时出错

标签 spring hibernate jpa datasource multiple-instances

我已经设法使用多个数据源配置 JPA,但是在启动我的服务器时出现以下错误(Websphere 自由):

org.hibernate.AnnotationException: @OneToOne or @ManyToOne onxxx.AccountBalance.currency references an unknown entity: xxx.Currency
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(T oOneFkSecondPass.java:109)
at org.hibernate.cfg.Configuration.processEndOfQueue( Configuration.java:1521)
at org.hibernate.cfg.Configuration.processFkSecondPas sInOrder(Configuration.java:1446)
at org.hibernate.cfg.Configuration.secondPassCompile( Configuration.java:1351)
at org.hibernate.cfg.Configuration.buildSessionFactor y(Configuration.java:1733)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>( EntityManagerFactoryImpl.java:94)
at org.hibernate.ejb.Ejb3Configuration.buildEntityMan agerFactory(Ejb3Configuration.java:905)

如果所有 DAO 都在同一个数据库中声明,应用程序将正确部署,但如果我将其中任何一个移动到第二个数据库,它就会失败。是否可以将 JPA 包(OneToOne、ManyToOne、ManyToMany)与多个数据源一起使用?

配置的相关部分:

上下文:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/xxxwas"
cache="true" resource-ref="true" lookup-on-startup="false"
proxy-interface="javax.sql.DataSource" />

<bean id="h2dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url"
value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;TRACE_LEVEL_SYSTEM_OUT=3" />
<property name="username" value="test" />
<property name="password" value="test" />
</bean>

<tx:jta-transaction-manager />

<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit .DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath:META-INF/persistence.xml</value>
</list>
</property>
<property name="dataSources">
<map>
<entry key="h2" value-ref="h2dataSource" />
<entry key="mysql" value-ref="dataSource" />
</map>
</property>
<!-- if no datasource is specified, use this one -->
<property name="defaultDataSource" ref="dataSource" />
</bean>

<bean id="integrationEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerE ntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceUnitName" value="integrationEntityManagerFactoryPU" />
<property name="jtaDataSource" ref="h2dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.Hibernat eJpaVendorAdapter">
<!-- <property name="showSql" value="true" /> -->
<property name="database" value="H2" />
<!-- <property name="generateDdl" value="true" /> -->
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerE ntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceUnitName" value="databaseEntityManagerFactoryPU" />
<property name="jtaDataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.Hibernat eJpaVendorAdapter">
<!-- <property name="showSql" value="true" /> -->
<property name="database" value="MYSQL" />
</bean>
</property>
</bean>

<jpa:repositories base-package="xxx.impl.repository.integration"
query-lookup-strategy="create-if-not-found"
entity-manager-factory-ref="integrationEntityManagerFactory">
</jpa:repositories>

<!-- Configures Spring Data JPA and sets the base package of my DAOs. -->
<jpa:repositories base-package="xxx.impl.repository"
query-lookup-strategy="create-if-not-found"
entity-manager-factory-ref="entityManagerFactory">
</jpa:repositories>

服务器.xml
  <dataSource id="xxxwas" jndiName="jdbc/xxxwas" supplementalJDBCTrace="true" type="javax.sql.XADataSource">
        <jdbcDriver javax.sql.ConnectionPoolDataSource="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource" javax.sql.DataSource="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" javax.sql.XADataSource="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" libraryRef="MySQLLib"/>
        <properties databaseName="xxx" password="xxx" portNumber="3306" serverName="localhost" user="root"/>
    </dataSource>

Web.xml
<resource-ref>
    <res-ref-name>jdbc/xxxwas</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

持久性.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="databaseEntityManagerFactoryPU" transaction-type="JTA">
        <class>xxx.impl.bo.AccountBalance</class>
       <!-- WORKS IF DEFINED HERE -->
        <!-- <class>xxx.impl.bo.Currency</class> -->
         <properties>
             <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
            <!-- <property name="hibernate.current_session_context_class"value="thread" /> -->
            <!--<prop key="hibernate.transaction.flush_before_completion">false</prop>-->
            <!--<prop key="hibernate.transaction.auto_close_session">true</prop>-->
            <!--<prop key="hibernate.current_session_context_class">thread</prop>-->
            <!--<prop key="javax.persistence.transactionType">JTA</prop>-->
            <!--<prop key="hibernate.connection.release_mode">auto</prop>-->

            <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
            <property name="hibernate.cache.use_query_cache" value="true"/>
            <property name="hibernate.cache.use_second_level_cache" value="true"/>
            <property name="net.sf.ehcache.configurationResourceName" value="ehcache_database.xml"/>
            <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>

            <!-- <property name="hibernate.archive.autodetection" value="class, hbm"/> -->
             <!-- <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>  -->
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy"/>
            <property name="hibernate.use_sql_comments" value="true"/>
            <property name="hibernate.generate_statistics" value="true"/>
        </properties>
    </persistence-unit>
     <persistence-unit name="integrationEntityManagerFactoryPU" transaction-type="JTA">
           <!-- DOES NOT WORK IF DEFINED HERE -->
        <class>xxx.impl.bo.Currency</class>
        <properties>
             <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
             <property name="hibernate.hbm2ddl.auto" value="create" />
        </properties>
    </persistence-unit>
</persistence>

最佳答案

我知道为时已晚,但我遇到了同样的问题。
我正在使用 Oracle 数据库,具有两个模式(用户)的同一个数据库
我的解决方案是让第一个用户访问第二个用户架构中的所有表。
之后,在 JPA 实体注释上,精确每个实体的模式。
这样,hibernate 使用 schema 生成 SQL 查询:

select field1, field2 from USER1.Table1 INNER JOIN USER2.TABLE2 ON .....
它是这样工作的,因为 user1 可以通过授权访问 user2 表,但是这两个模式必须在同一个数据库中,否则你必须创建一个 dblink 和一个同义词。

关于spring - 将 OneToOne/ManyToOne 与 JPA 和多个数据源一起使用时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21133131/

相关文章:

java - RestTemplate/HttpClient 的缺点/优点

java - Spring中的任务执行与调度

java - 检查对象是否被引用,以防止在不修改数据库的情况下软删除

java - 如何按创建日期搜索数据库中的配置文件

java - @SequenceGenerator 的架构属性在 Hibernate 中不起作用

java - Angular : Detect Logout after Server Restart

java - Spring 初学者 没有可用的上下文

java - 在单独的表中映射 @Embeddable

java - 如何通过持久性动态配置数据库连接