2012-08-27 3 views
0

데이터베이스에 데이터를 유지하고 삭제하는 웹 서비스가 있습니다. 데이터베이스에서 어떤 사용자 이름이 데이터베이스의 어떤 행을 터치했는지 추적하려고합니다. 각 테이블에는 사용자 이름을 저장할 열이 있습니다 (원하는 경우 열 업데이트). 또한 트랜잭션에 대해 userID를 사용하고 해당 테이블을 삽입하려고 시도한 사용자 이름과 암호로 업데이트하는 테이블에 트리거가 있습니다. JPA가 데이터를 지속 할 때 그 사용자 이름이 테이블에 던져 질 수 있도록 JPA 객체의 일부 종류를 업데이트하고 클라이언트로부터 전달 된 사용자 이름을 얻을 수있는 열린 JPA의 방법이 있습니까?OpenJPA 감사 기능

답변

1

가장 깨끗한 방법 중 하나는 엔티티에 공통적 인 "mapped" superclass을 구현하고 @PrePersist 주석이있는 메소드를 사용하여 필드를 채우는 것입니다.

public interface AuditedEntity { 
    public static void setLastUpdatedBy(String username); 
} 

@Entity 
@EntityListeners({ MyLogger.class, ... }) 
public class Employee implements AuditedEntity { 
    // ... 
} 

public class MyLogger { 
    @PreUpdate 
    @PrePersist 
    public void onChange(Object o) { 
     if(o instanceof AuditedEntity) { 
      String user = .... // Do whatever is needed to get the current user 
      ((AuditedEntity) o).setLastUpdatedBy(user); 
     } 
    } 

    @PostPersist 
    @PostUpdate 
    public void logChange(Object o) { 
     // Log the successful operation 
    } 
} 
+0

하나 (예를 들어 오라클을 사용) SYS_CONTEXT을 설정할 수있는 방법이 있나요 :

@MappedSuperclass public class AuditedEntity { @Id protected Integer id; protected String lastUpdatedBy; // Setters and getters here @PreUpdate @PrePersist public void onChange() { String user = .... // Do whatever is needed to get the current user setLastUpdatedBy(user); } } @Entity public class Employee extends AuditedEntity { // .... } 

또 다른 옵션은 별도의 수신기를 사용하는 것입니다? 나는 일종의 수퍼 클래스 사용을 피하려고 노력했다. 하지만 내가해야한다면. – SoftwareSavant

+0

JPA 코드에서 데이터베이스 관련 내용을 명확하게 처리하려고합니다. 앞으로 데이터베이스 엔진을 변경하거나 단위 테스트를 위해 메모리 내장 데이터베이스를 사용할 가능성이 없어집니다. – anttix

+0

mappedsuperclass를 혼란스럽게하지 않으려면 리스너를 사용할 수 있습니다 (단점이 있습니다). 방법에 대한 업데이트 된 게시물을 참조하십시오. – anttix