2014-10-11 93 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」,以確定適當的一個。