【问题标题】:Override NativeQuery at Runtime在运行时覆盖 NativeQuery
【发布时间】:2014-10-11 18:41:00
【问题描述】:

我在我的项目中使用带有 SqlServer 的 OpenJPA,并且我需要对特定查询使用本机 SqlServer 语法。为此,我一直在使用 NativeQuery 注释,效果很好。

但是,当我需要使用 Derby 作为我的数据库运行单元测试时,问题就出现了。事实证明,Derby 不支持我的 NativeQuery 的确切语法。我的想法是用“Derbified”版本替换 NativeQuery 来运行测试。但是,我还没有找到一种方法来做到这一点。

有没有办法在运行时覆盖或重新定义实体的 NativeQuery?

【问题讨论】:

    标签: jpa derby


    【解决方案1】:

    我将使用 persistence.xml 定义两个 peristence-unit 元素(一个用于 SqlServer,另一个用于 Derby),其中包含 named-native-query 的专用 orm.xml

    persistence.xml

    <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="sqlserver-pu">
            <mapping-file>META-INF/orm-sqlserver.xml</mapping-file>
            ...
        </persistence-unit>
    
        <persistence-unit name="derby-pu">
            <mapping-file>META-INF/orm-derby.xml</mapping-file>
            ...
        </persistence-unit>
    </persistence>
    

    orm-sqlserver.xml

    <entity-mappings version="2.0"
        xmlns="http://java.sun.com/xml/ns/persistence/orm" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm 
        http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">
    
        <named-native-query name="findFirst" result-class="com.tyler.example.order">
            <query>SELECT TOP 1 * FROM Order</query>
        </named-native-query>
    </entity-mappings>
    

    orm-derby.xml

    <entity-mappings version="2.0"
        xmlns="http://java.sun.com/xml/ns/persistence/orm" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm 
        http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">
    
        <named-native-query name="findFirst" result-class="com.tyler.example.order">
            <query>SELECT * FROM Order FETCH FIRST ROW ONLY</query>
        </named-native-query>
    </entity-mappings>
    

    通过这种方法,您可以提高代码的互操作性,因为实体(可跨数据库移植)与查询(特定于供应商)分离。您只需在运行时选择合适的持久性单元并执行给定的查询(它们必须具有相同的名称)。

    我想到的另一种方法是使用具有不同 namequery 属性的 @NamedNativeQuery 注释为每个实体定义两次命名本机查询,但在运行时您可能需要一些“ifology”来确定一个合适的。

    【讨论】:

      猜你喜欢
      • 2020-04-15
      • 1970-01-01
      • 2014-06-26
      • 2015-08-11
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 2021-11-21
      • 1970-01-01
      相关资源
      最近更新 更多