2011-09-06 44 views
1

我們有以下關係:
汽車屬於某人。
一個人可以擁有很多汽車。僅使用主鍵進行休眠代理加載

下面是汽車的映射:

<hibernate-mapping package="fr.recouv.scribe.core.bo"> 
<class name="Car" table="car"> 
<id name="id" column="id_car" unsaved-value="0"> 
    <generator class="sequence"> 
    <param name="sequence">car_id_car_seq</param> 
    </generator> 
</id> 
<many-to-one name="person" update="false" column="id_person" class="Person" /> 
<property 
</class> 

我有這個簽名web服務:

public void insert(Car car, int idPersonOwner) 

我想插入了一輛車給他的ID特定的人。 現在我的代碼看起來是這樣的:

Car car = new Car(); 
Person owner = personDao.get(idPersonOwner); 
car.setPerson(owner); 
carDao.save(car); 

而對於personDao.get(idPersonOwner)Hibernate實現看起來像

public Person get(in idPerson){ 
return session.get(Person.class, id); 
} 

缺點這種方法的:

  • 的所有Person對象正在加載,即使我需要從一個SQL視圖只是他的ID
  • 的操作可能產生超過2個查詢,如果人的映射進化(如懶加載設置爲false等)

我實際的解決方法: 這是直接的外鍵映射到一個整數

<property column="id_person" name="idPerson" /> 

該解決方案不是面向對象的,不太美觀。 如果明天我需要找回一個車,我不得不重新映射人的物體,像以前的和更新的所有者=假

是否有可能只加載一個人的代理給出他的ID,這將導致與查詢 以驗證此人是否與他的主鍵一起存在,並且如果他們被調用,可選地將其他字段加載到懶惰模式。

我已經嘗試過session.load,但這不是解決方案。該對象從不爲空(不存在查詢測試其存在),或者不會拋出異常,直到您訪問其他字段 以從數據庫中加載實際對象。

回答

3

是的,這正是session.loadEntityManager.getReference如果使用JPA)。它假設實體存在,則將對象加載到對象。

當然,如果在提交時外鍵約束因爲該人實際上不存在而中斷,您可能會有異常。但是如果在提交之前某些其他交易刪除了該人,您也可以使用Session.get

如果你真要查這個人存在,執行專門的查詢只返回一個布爾值(或計數),以及使用Session.load當你知道這個人存在:

Number count = 
    session.createQuery("select count(p.id) from Person p where p.id = :theId") 
      .setLong("theId", theId) 
      .uniqueResult(); 
if (count.intValue() > 0) { 
    Person p = session.load(Person.class, theId); 
} 
else { 
    // throw exception 
} 
+0

我希望冬眠有東西已經是:(但非常感謝您的答案! –