【问题标题】:JPA MetaDataException for different datasources不同数据源的 JPA MetaDataException
【发布时间】:2016-05-27 01:31:57
【问题描述】:

在我的项目中使用不同的数据源持久性时,我遇到了 JPA Criteria API 的问题。

有两个PU使用不同的数据源:

<persistence-unit name="analysis" transaction-type="RESOURCE_LOCAL">
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <non-jta-data-source>AnalysisDS</non-jta-data-source>
    <class>entity1</class>
    <class>entity2</class>
    <class>entity3</class>

<persistence-unit name="reaction" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <non-jta-data-source>ReactionDS</non-jta-data-source>
    <class>someEntity1</class>
    <class>someEntity2</class>
    <class>someEntity3</class>

Spring 加载它,在 applicationContext 中

<bean id="defaultAnalysysDataSource"
      class="org.springframework.jndi.JndiObjectFactoryBean"
      lazy-init="default">
    <property name="jndiName" value="AnalysisDS"/>
    <property name="lookupOnStartup" value="false"/>
    <property name="cache" value="true"/>
    <property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>

<bean id="defaultReactionDataSource"
      class="org.springframework.jndi.JndiObjectFactoryBean"
      lazy-init="default">
     <property name="jndiName" value="ReactionDS"/>
     <property name="lookupOnStartup" value="false"/>
     <property name="cache" value="true"/>
     <property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>

在我的 DAO 中,我可以使用 EntityManager 处理这个 PU,例如 我正在使用的 ReactionDS

 @PersistenceContext(unitName = "reaction")
 private EntityManager entityManager;

所有工作都完成了 - 简单的查询和 JPQL 表达式。 但是当我想介绍我的 DAO JPA Criteria API 像这样:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
...

getCriteriaBuilder() 方法工作后出现异常:

Caused by: <openjpa-2.4.0-r422266:1674604 fatal user error> org.apache.openjpa.util.MetaDataException: Errors encountered while resolving metadata.  See nested exceptions for details.
    at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:675)
    at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:418)
    at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:389)
    at org.apache.openjpa.persistence.meta.MetamodelImpl.(MetamodelImpl.java:86)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:348)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.getCriteriaBuilder(EntityManagerFactoryImpl.java:332)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

...
Caused by: <openjpa-2.4.0-r422266:1674604 fatal user error> org.apache.openjpa.util.MetaDataException: Table "ANALYSIS.ENTITY1" given for "entity1" does not exist.
    at org.apache.openjpa.jdbc.meta.MappingInfo.createTable(MappingInfo.java:532)
    at org.apache.openjpa.jdbc.meta.ClassMappingInfo.getTable(ClassMappingInfo.java:317)
    at org.apache.openjpa.jdbc.meta.ClassMappingInfo.getTable(ClassMappingInfo.java:339)
    at org.apache.openjpa.jdbc.meta.strats.FullClassStrategy.map(FullClassStrategy.java:73)
    at org.apache.openjpa.jdbc.meta.ClassMapping.setStrategy(ClassMapping.java:392)
    at org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(RuntimeStrategyInstaller.java:55)
    at org.apache.openjpa.jdbc.meta.MappingRepository.prepareMapping(MappingRepository.java:410)
    at org.apache.openjpa.meta.MetaDataRepository.preMapping(MetaDataRepository.java:769)
    at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:658)
    ... 147 more

JPA 中的问题根本原因,因为他试图在 Reaction PU 中使用来自 Analys 的表并为位于不同数据源中的实体提取所有元类,但对它们的访问是在一个中完成的。

但是当我将 Entity1 上的选择授予 ReactionDS 时 - 所有工作都完成了。 (因为我可以使用 Select * from Analysis.Entity1 from 反应)

问题 - 如何使元模型类选择仅在 EntityManager 中的指定 DS 内工作(在当前示例中 - 反应,不与分析一起使用)?

p.s 数据库是 Oracle,使用 Weblogic 12.1.3 和 OpenJpa2.4。 编译时使用 maven 插件自动生成元模型:

<plugin>
    <groupId>org.bsc.maven</groupId>
    <artifactId>maven-processor-plugin</artifactId>
    <executions>
        <execution>
            <id>process</id>
            <goals>
                <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
                <processors>
                    <processor>org.apache.openjpa.persistence.meta.AnnotationProcessor6</processor>
                </processors>
                <optionMap>
                    <openjpa.metamodel>true</openjpa.metamodel>
                </optionMap>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa</artifactId>
            <version>${openjpa.version}</version>
        </dependency>
    </dependencies>
</plugin>

【问题讨论】:

    标签: java jakarta-ee jpa-2.0 openjpa metamodel


    【解决方案1】:

    我认为您可能对 Spring Framework 数据源声明感到困惑。

    这些 bean 不定义您的数据源,它们只是为其他 Spring 组件提供一种访问已在您的服务器中配置的数据源的方法。 JPA 根本不使用这些。

    因此,您的问题在于您在 WebLogic 服务器中定义的数据源。看起来您已经定义了两个数据源来引用同一个数据库实例。

    【讨论】:

    • 感谢您的回答。在 Weblogic 中 jdbc 使用不同的数据源,并且一切正常,如果我不尝试使用 Criteria API 代替 JPQL 查询。带有 CriteriaBuilder 和数据源检测的元模型中的问题
    • 如果发生这种情况,那么您在 OpenJPA 中发现了一个错误,应该按照Found a bug? 中的说明进行报告。
    猜你喜欢
    • 2023-03-10
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 2016-05-26
    • 2011-01-28
    相关资源
    最近更新 更多