2014-10-11 68 views
0

我在我的项目中使用OpenJPA和SqlServer,并且我需要为特定查询使用本机SqlServer语法。为此,我一直在使用NativeQuery注解,并取得了很好的结果。在运行时覆盖NativeQuery

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

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

回答

2

我会使用的persistence.xml以限定两个peristence-unit元件(一个用于SqlServer的,另一个用于德比)与专用orm.xml中含有named-native-query

的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> 

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

是进入我的脑海里的另一种方法是两次定义一个名为本地查询使用@NamedNativeQuery标注不同namequery属性每个实体,但在运行时,你会那么可能需要一些“ifology”,以确定适当的一个。