2009-06-17 4 views
0

먼저 질문을 설정하십시오.엄청난 선택 대신에 간단한 업데이트를하기 위해 최대 절전 모드로 전환

내가 가진 것은> 테이블 : Customer, Address, Order, OrderItems입니다. 각각은 Hibernate Annotation을 사용하여 매핑되고 Spring DAO/Services 계층을 통해 액세스됩니다.

중복 고객을 함께 병합하려고합니다. 따라서 고객 B와 관련된 모든 주문과 주소는 고객 A를 가리 키도록 고객 ID 외래 키를 업데이트해야합니다. 그런 다음 고객 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(); 

그리고 내가 고객 A를 고객 B의 주소와 순서의 모든 객체를 이동하고 모두 고객에

return (Customer) this.getHibernateTemplate().merge(customer); 

을 실행

나는 다음 최대 절전 모드 기준을 사용하여 개체를 얻을 사물. 이로 인해 관련된 모든 객체 (예 : OrderItems, 제품, ProductType, ProductPricingTmpl 등)를 가져 오는 많은 수의 select 문이 작성됩니다.

이러한 선택을 제거해야합니다. 그들이 존재하지 않는다면 쿼리는 정상적으로 보이고 효율적일 것입니다! 업데이트 된 쿼리는 완벽하고 동적입니다.

아이디어가 있으십니까?

+0

이 비슷한 게시물을 확인하십시오. http://stackoverflow.com/questions/161224/what-are-the-differences-between-the-different-saving-methods-in-hibernate –

답변

2

실마리는 merge() 작업을 선택했을 수 있습니다. 최대 절전 모드의 javadoc에서 :

복사 동일한 식별자를 가진 영속 객체 위에 지정된 오브젝트 의 상태. 영구 인스턴스가 현재 과 관련되어 있으면 이로드됩니다.

그래서 당신은 Hibernate가 모든 데이터를 수정하기 전에 강제로로드 할 것이다.

는()로 업데이트, 서로 다른 동작을 시도

업데이트 영구 인스턴스 으로 분리 주어진 인스턴스 식별자.

Hibernate는 아무런 약속을하지 않아도 어쨌든로드해야한다고 결정할 수도 있습니다. dynamicUpdates = true 설정은 실제로 동적 업데이트를 실행하기 전에 시작될 항목을 알아야하기 때문에 실제로 상황을 악화시킬 수 있습니다.

관련 문제