2009-06-17 61 views
0

讓我們先設置問題。讓Hibernate做簡單的更新,而不是大量的選擇然後更新

我所擁有的是> 4個表格:Customer,Address,Order,OrderItems。每個都使用Hibernate Annotations進行映射,並通過Spring DAO /服務層進行訪問。

我想要做的是將重複的客戶合併在一起。所以真正需要發生的是與客戶B相關的所有訂單和地址,需要更新他們的customer_id外鍵以指向客戶A.然後客戶B必須設置其禁用位。

而不是發送這些簡單的查詢到我們的數據庫,休眠變得瘋狂,併發出大量的選擇,然後更新查詢。特別是,它選擇訂單上附加的所有訂單項目(因爲這是定義爲EAGER,並且此點不可更改)。要獲得選擇更新之前阻止事情發生我嘗試添加休眠實體註釋就經常javax.persistence.Entity像的頂部:

@org.hibernate.annotations.Entity(dynamicUpdate = true, selectBeforeUpdate = false, dynamicInsert = true) 

這似乎沒有任何影響,除了與簡單的查詢,其中僅在一個更新的單品表。

我得到使用下面的休眠條件的對象:

  Criteria c1 = null; 
      Criteria c2 = null; 
      Criteria c = session.createCriteria(Customer.class); 
      c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 

      if(resultLimit>0) c.setMaxResults(resultLimit); 
      if(timeout>0) c.setTimeout(timeout); 
      for(String filter: sqlFilters) { 
       if(filter.indexOf("{alias}.customer_")!=-1) c.add(Restrictions.sqlRestriction(filter)); 
       else if(filter.indexOf("{alias}.address_")!=-1 && addrsAttached) { 
        if(c1==null) 
         c1 = c.createCriteria("addresses").setFetchMode("type", FetchMode.JOIN); 
        c1.add(Restrictions.sqlRestriction(filter)); 
       } else if(filter.indexOf("{alias}.order_")!=-1 && ordersAttached) { 
        if(c2==null) 
         c2 = c.createCriteria("orders").setFetchMode("orderItems", FetchMode.SELECT); 
        c2.add(Restrictions.sqlRestriction(filter)); 
       } 
      } 
      return (List<Customer>) c.list(); 

接我一招全部來自消費者B的地址和命令對象的客戶A和運行

return (Customer) this.getHibernateTemplate().merge(customer); 
兩個客戶

對象。這最終建立一噸的select語句得到所有的相關對象的(即的OrderItems,產品,ProductType,ProductPricingTmpl,等..)

我需要得到這些選擇刪除!如果他們不在那裏,查詢看起來很正常,而且效率很高!更新輸出的查詢是完美的和動態的。

任何想法?

+0

結算這個類似的帖子:http://stackoverflow.com/questions/161224/what-are-the-differences-between-the-different-saving-methods-in-hibernate – 2009-06-18 12:52:31

回答

2

線索可能在您選擇merge()操作。從Hibernate的Javadoc:

複製給定對象 的狀態到具有 相同標識符持久對象。如果沒有 持續實例當前 與會話關聯,則會加載 。

所以你迫使Hibernate在修改它之前加載所有的數據。

嘗試不同的操作,諸如更新():

更新持久實例與 給定的分離 實例的標識符。

雖然沒有承諾,但Hibernate可能會決定它需要加載它。 dynamicUpdates = true配置實際上可能會讓它變得更糟,因爲它在發佈動態更新之前需要知道啓動的內容。