2010-04-20 2 views
2

나는 주석이없는 직선의 Hibernate 3.0을 사용하고있다.Hibernate를 이용한 Create_Date와 Update_Date 컬럼의 생성

도메인 객체를 저장하거나 업데이트 할 때 데이터베이스 트리거를 사용하는 것과는 반대로 Hibernate가 자동으로 CREATE_DT 및 UPDATE_DT 필드를 생성하고 싶습니다.

이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

배경은 여러 개체가 들어있는 클라이언트에서 개체 그래프가 전달되는 것입니다. 일부는 삽입되고 다른 일부는 업데이트됩니다. 나는 클라이언트에서 날짜를 설정할 수 있지만 이것은 나쁜 생각 일 것입니다. 서버에 날짜를 설정하면 그래프를 통해 소총을 조사하고 변경 사항을 감지해야합니다.

하이버 네이트는 이런 일을 할 수있는 설비가 있지만 나에게 뛰어 들지는 않는다. 트리거를 사용하지 않고이 작업을 수행하는

답변

1

최대 절전 모드 방법 설정 (전체 목록은 org.hibernate.event 패키지를 보라) Hibernate의 event architecture을 사용하고 PreInsertEvent, PreUpdateEvent 또는 SaveOrUpdateEvent 청취자를 등록하고 생성/업데이트를 업데이트 할 것 날짜.

또 다른 옵션 중 하나를 Session -scoped 또는 -scoped SessionFactory에서, 업데이트 onSave(...)에서onFlushDirty(...)에서 업데이트 날짜 날짜 생성 설정하기 위해, interceptor을 사용하는 것입니다.

기타 옵션은 previous answer 일 수 있습니다.

0

나를 달성하기위한 가장 간단한 방법은 해당 필드를 개체 클래스의 속성으로 사용하고 생성자를 통해 개인적으로 설정하는 것입니다. 속성 값이 변경되면 DateUpdated (예를 들어)를 DateTime.Now (또는 Java에있을 수있는 모든 것)로 설정합니다.

엔티티가 지속되면 자동으로 해당 날짜를 저장하고 기본 데이터베이스에 유지합니다.

이것은 Hibernate와 직접적으로 관련이 없지만,이 솔루션은 인터셉터를 사용하는 것보다 구현하기가 더 쉽다고 생각합니다.

희망이 도움이됩니다.

+0

그래서 당신은'setUpdateDate (...)'호출로 ** 모든 ** 당신의 세터를 오염 : 아래

는 인터셉터에 대한 코드? 나는 이것을 (당신이 설정하고 완료 한) 요격기보다 쉽게 ​​발견하지 못하고 매우 추악합니다. –

+0

일종의 이벤트를 유발하는 것 이상은 아닙니다. –

+0

그게 무슨 소리 죠? 이러한 이벤트가 있으며 최대 절전 모드로 인해 트리거됩니다. 따라서 리스너를 차별화하여 활용할 수는 없습니다. 어쩌면 당신은 문서를 읽어야합니다. –

0

나는 파스칼의 대답을 정답으로 확인하고 있는데, 그는 세부 사항과 예제 코드를 제공 한 문서의 요점을 직접 지적했다. 그러나 독자를 위해 여기에 더 자세히 설명하겠습니다.

나는 인터셉터뿐만 아니라 최대 절전 모드 이벤트를 시도하고 인터셉터가 내 상황에서 더 잘 작동한다는 것을 알았다. 구현하기가 비교적 쉬웠습니다.

도움 주셔서 감사합니다.

public class AuditInterceptor extends EmptyInterceptor { 

    private Log log = LogFactory.getLog(this.getClass()); 

    private int updates; 
    private int creates; 

    @Override 
    public boolean onSave(Object entity, Serializable id, Object[] state, 
      String[] propertyNames, Type[] types) { 
     if (entity instanceof AuditableVO) { 
      creates++; 
      // Find the create date and change it 
      for (int i=0; i < propertyNames.length; i++) { 
       if (propertyNames[i].equals("createDate")) { 
        state[i] = new Date(); 
        return true; 
       } 
      } 
     } 
     return false; 
    } 
    @Override 
    public boolean onFlushDirty(Object entity, Serializable id, 
      Object[] currentState, Object[] previousState, 
      String[] propertyNames, Type[] types) { 
     if (entity instanceof AuditableVO) { 
      updates++; 
      // Find the update date and change it 
      for (int i=0; i < propertyNames.length; i++) { 
       if (propertyNames[i].equals("updateDate")) { 
        currentState[i] = new Date(); 
        return true; 
       } 
      }   
     } 
     return false; 
    } 
    @Override 
    public void afterTransactionCompletion(Transaction tx) { 
     if (tx.wasCommitted()) { 
      log.info("Creations: " + creates + ", Updates: " + updates); 
     } 
     creates = 0; 
     updates = 0; 

     super.afterTransactionCompletion(tx); 
    } 
} 
관련 문제