2013-08-27 6 views
1

엔티티 중 하나가 변경되거나 작성되는 즉시 로그 항목을 작성하려고합니다. 이를 위해 AbstractEntity 클래스에 EntityListener를 등록했습니다. AbstractEntity에는 LogEntry 목록이 있으며이 목록의 계단식 유형은 ALL입니다 (모든 엔티티는 AbstractEntity에서 상속받습니다). 내에 EntityListener의JPA 2.1 JPA EntityListener 내의 엔티티 생성

현재 구현 :

public class EntityChangeListener { 

    @Inject 
    SessionController sessionController; 

    @PreUpdate 
    public void preUpdate(AbstractEntity entity) { 
     createLogEntryFor(entity, LogEntry.ChangeType.UPDATED); 
    } 

    @PrePersist 
    public void prePersist(AbstractEntity entity) { 
     createLogEntryFor(entity, LogEntry.ChangeType.CREATED); 
    } 

    private void createLogEntryFor(AbstractEntity entity, LogEntry.ChangeType changeType) { 
     if (!(entity instanceof LogEntry)) { 
      Date now = Calendar.getInstance().getTime(); 
      LogEntry logEntry = new LogEntry(); 
      logEntry.setCreator(sessionController.getCurrentUser()); 
      logEntry.setAbstractEntity(entity); 
      logEntry.setChangeDate(now); 
      logEntry.setChangeType(changeType); 
      entity.getLogEntries().add(logEntry); 
     } 
    } 
} 

문제는 캐스케이드 모든 입력 사용하지만 로그 항목이 유지되지 않습니다 것입니다. 또한 LogEntry를 수동으로 유지하기 위해 계단식 유형을 제거하고 LogEntryService (CRUD 메소드가있는 SLSB)를 삽입하려고했지만 효과가 없습니다.

@PostPersist 및 @PostUpdate를 사용하면 동일한 문제가 발생합니다.

JPA 공급자는 EclipseLink (2.5.0)입니다.

최대 절전 모드로 전환하고 Envers를 사용하는 것은 옵션이 아닙니다.

답변

1

prePersist 이벤트는 변경이 계산되기 전에 prePersist가 호출 될 때, 작동합니다.

preUpdate의 경우 preUpdate 이벤트가 호출되기 전에 변경 사항이 계산되므로이 기능이 작동하지 않으므로 추가 변경이 너무 늦습니다.

대신 고급 옵션에 액세스 할 수 있도록 EclipseLink DescriptorEvents를 사용할 수 있습니다. Session을 가져 와서 insertObject()를 직접 호출하여 로그 항목을 강제로 삽입하거나 객체 또는 UnitOfWork ChangeSet을 변경할 수 있습니다. 또한

은 EclipseLink의 역사 지원을 고려

, http://wiki.eclipse.org/EclipseLink/Examples/JPA/History

는 EclipseLink는 커밋 두 개의 패스를 할 수있는 이벤트, 그것은이 투표에 대한 버그를 기록하십시오 개체를 변경할 수 있도록 옵션을 제공 (또는 찾아야한다

투표 기존의 경우).

+0

좋아,하지만 최대한 빨리 DescriptorEvents를 사용할 때 내가 체크 ifthe 엔티티를 구현해야 변경되었습니다 나는 Entitylisteners에서 CDI 콩을 주입 JPA 2.1의 멋진 새로운 기능을 잃게됩니다. 권리? – mare