2015-01-27 2 views
0

기본적으로 엔티티를 삭제할 수없는 것으로 설명하는 기본 클래스 유형이 있습니다. 이클립스 링크의 디스크립터 커스터마이징 API를 사용하여 기본 삭제 SQL을 덮어 쓰고 비 아카이브 된 엔티티 만 리턴하는 추가 기준을 추가한다.EclipseLink DescriptorCustomizer가 상속 된 부속 유형을 지원하지 않습니까?

이는 Archiveable 클래스를 직접 확장하는 모든 클래스에서 작동합니다. Archiveable 클래스를 확장하는 MappedSuperClass가 아닌 클래스를 확장하는 클래스는 사용자 정의 프로그램을 상속하지 않습니다. 아래 예제를보십시오 :

필자는 EclipseLink 2.5.1을 사용하고 있습니다. 요약

/** 
* Base Abstract class that implements archiving functionality 
*/ 
@MappedSuperClass 
@Customizer(ArchiveableCustomizer.class) 
public abstract class Archiveable { 

    @NotNull 
    @Column(name = "DELETED) 
    private Boolean archived = false;  

    // omitted: getters/setters  
} 

/** 
* The EclipseLink customizer implementation (followed their docs) 
*/ 
public class ArchiveableCustomizer extends DescriptorEventAdapter 
     implements DescriptorCustomizer { 

    @Override 
    public void customize(ClassDescriptor descriptor) throws Exception { 
     // omitted: override delete string 

     // this is the piece not working 
     descriptor.getQueryManager().setAdditionalCriteria("this.archived = false"); 
    } 
} 


/** 
* Base class for entities that are stored in the Catalog table. All are archived 
*/ 
@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name = "TYPE", DiscriminatorType.STRING) 
public abstract class Catalog extends Archiveable { 
    // omitted: shared columns, not relevant. 
} 

/** 
* This class does <b>NOT</b> work 
*/ 
@Entity 
@DiscriminatorValue("CAR_TYPE") 
public class CarType extends Catalog { 
    // omitted: class details, not relevant 
} 

/** 
* Class that does not extend the Catalog class but the Archiveable 
* class directly. This class can be queried correctly with the 
* additional criteria 
*/ 
@Entity 
public class Car extends Archiveable { 
    // omitted: clas details, not relevant 
} 

, CarTypeArchiveableCustomizer 선택하지 않는 클래스입니다. 클래스 CarArchiveableCustomizer입니다.

+1

이것은 의도적으로 설계된 동작입니다. mappedSuperClass 인 경우 Archiveable 클래스에 대한 설명자가 없기 때문에 사용자 정의 프로그램은이를 가져 오는 엔티티 설명자에서 실행됩니다. 상속이 수반되면 루트에는 설명자가 있고 사용자 정의 프로그램이 실행되지만 각 하위 클래스에는 자체 설명자가 있으므로 자체 사용자 정의 프로그램 클래스가 필요합니다. – Chris

+0

@Chris 응답 해 주셔서 감사합니다. 내 예제가 잘못되었으므로 예제를 업데이트했습니다. 이것은 귀하의 응답을 명확히하거나 변경할 수 있습니다. – predhme

+1

내 설명을 확인하지 않습니다. MappedSuperClass 클래스에는 디스크립터 자체가 없으므로 모든 설정이이 클래스에서 가져와 하위 클래스 엔터티 설명자에 적용됩니다. 커스터마이져는 상속받을 수 없으며, 할당 된 엔티티에서만 실행된다. 이것은 서브 클래스에 적용되는 JPA 이벤트 리스너와는 다르다. 또한 루트 엔티티의 일부 변경 사항은 서브 클래스에서 볼 수 있습니다. 상속 그래프는 모두 예를 들어 같은 캐시를 사용하고 공통 맵핑에 대한 변경 사항은 하위 디스크립터에서 볼 수 있지만 그 점은 확실하지 않습니다. – Chris

답변

1

EclipseLink의 내부에서 MappedSuperClass 클래스는 디스크립터 자체를 가지고 있지 않으므로 모든 설정을 가져 와서 하위 클래스 엔티티 설명자 (사용자 정의 프로그램 포함)에 적용합니다.

상속을 사용하면 계층 구조의 각 엔터티에 고유 한 설명자가 있으며 매핑 및 기타 설정이 상속되는 동안 설명자 사용자 지정자는 할당 된 설명자 (이 경우에는 루트)에서만 실행됩니다. 또한 루트 엔티티의 일부 변경 사항은 서브 클래스에서 볼 수 있습니다. 상속 그래프는 모두 예를 들어 같은 캐시를 사용하고 공통 매핑에 대한 변경 사항은 자식 설명자에 표시 될 수 있지만 그 점은 확실하지 않습니다.

+0

그냥 후속 질문. '@ Customizer'를'CarType' 클래스에 적용했지만 모델은'Archiveable' 클래스에 지정된 추가 기준을 적용하지 않습니다 **. 카디 타입 클래스에'@ Customizer'를 직접 기술하면 그 기술 어가 올바르게 적용될 것으로 예상됩니까? – predhme