2017-08-04 94 views
0

是否可以從Hibernate(5)中檢索實體之間的關係是如何配置的?搞清楚Hibernate是如何配置實體關係的

我的用例如下:我有一個Web服務提供(讀取)訪問關係數據庫中的數據。數據由多個實體組成,其中一些通過外鍵(通常的一對一,一對多,多對一,多對多)相關聯。當請求數據時,客戶端可以指定一個過濾器,並且在過濾器中,他們可以自由地遍歷實體關係。有些東西需要將過濾器轉換成Hibernate理解的東西。目前,我們正在生成Criteria

舉例來說,假設我們有2個實體AB,其中A.bees屬性指的是B的集合。這在Hibernate中映射爲B中的外鍵列指的是主鍵A。然後用戶可以請求具有至少一個B的所有A和以'Bla'開始的B.name。該請求指定我們正在尋找A類型的結果,它的過濾器部分看起來是這樣的:

<like> 
    <property>bees.name</property> 
    <literal>Bla*</literal> 
</like> 

問題是:我的服務不控制Hibernate映射,因此不知道如何關係被配置,甚至存在哪些實體。它只是加載映射,翻譯和應用過濾器,並吐出任何由Hibernate返回的數據。我無法按照規範更改請求內容(實際上是OGC篩選器)。

到目前爲止,我能夠找到合適的實體並遵循屬性路徑,沿途遇到屬性AssociationType s和EntityMetadata並將所有過濾器元素轉換爲單獨的Criterion s。我無法做的是找出實體是如何相關的:在這個例子中,「B有一個外鍵,指的是主鍵A」。誰能告訴我如何獲得這些信息?

回答

0

原來我誤會了如何應該在Hibernate中完成。我用的是標準的API來生成查詢,我會寫我自己:

session.createCriteria("A") 
     .add(Property.forName("id").in(
       DetachedCriteria.forEntityName("B") 
           .add(Restrictions.like("name", "Bla%")) 
           .setProjection(Projections.property("fk_a")))) 

結果查詢是(幾乎)

SELECT a.* 
    FROM A a 
WHERE a.id IN (SELECT b.fk_a 
        FROM B b 
       WHERE b.name LIKE 'Bla%') 

問題是我不知道的名字idfk_a


我應該做的而不是(現在正在做)只是讓Hibernate做連接。

session.createCriteria("A") 
     .createAlias("B", "b") 
     .add(Restrictions.like("b.name", "Bla%")) 
     .setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE) 

從這個結果查詢是(幾乎)

SELECT a.*, b.* 
    FROM A a INNER JOIN B b ON a.id = b.fk_a 
WHERE b.name LIKE 'Bla%') 

現在我也不需要知道主鍵和外鍵屬性的名稱。

這種方法的一個明顯缺點是,當A和相關B的笛卡爾乘積被返回時,更多的數據從服務器傳輸到客戶端。通過表明我們只對不同的根實體感興趣,我們得到了預期的答案。雖然變壓器在客戶端運行,但它確實無助於減少流量。

0

我不知道我很理解你的數據庫的訪問權限,但如果你能連接到數據庫,你可以使用JDBC的DatabaseMetaData的類,它的出口鍵方法: https://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getExportedKeys(java.lang.String,%20java.lang.String,%20java.lang.String)

+0

我想避免直接與數據庫交談。原因是:1)Hibernate的配置已經包含了所有必要的細節和2)我將處理不同類型的數據庫。 – jackrabbit

+0

hibernate的SessionFactory元數據訪問器怎麼樣? https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/SessionFactory.html 您可以訪問'所有類元數據'和類(實體)特定的。 –

+0

感謝您的努力,但是我無法爲所有連接類型編寫特殊情況下找不到所需的信息。我已經解決了一個不同的方法。 – jackrabbit