2010-06-09 1 views
20

에 DiscriminatorValue을 얻는 방법을 우리가런타임

@Entity 
@DiscriminatorValue("APS") 
public class ApplicationProcessScheme extends ApplicationProcess { 
} 

@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // optional annotation as this is default 
@DiscriminatorColumn(name = "apType", discriminatorType = DiscriminatorType.STRING, length = 255) 
@DiscriminatorValue("AP") 
public class ApplicationProcess { 
} 

그리고 이것은 지금은 ApplicationProcessDiscriminatorValueAP or APS의 경우 런타임에 알 필요가 다음과 같은 클래스. jpa가 자동으로 처리하므로이 값을 가져올 방법이 없습니다.

우리는 매개 변수로 ApplicationProcess을 사용하는 메서드를 호출하고 어떤 유형인지 확인하기 위해 instanceof을 사용하지 않으려합니다. 나는 우리가 매개 변수로 ApplicationProcess을 소요하는 방법을 요구하고있다

applicationProcess.getApType().equals("AP"); 

답변

34

당신은 읽기 전용 속성으로 당신의 판별을 매핑 할 수 있습니다 :

public class ApplicationProcess { 

    ... 

    @Column(name = "apType", insertable = false, updatable = false) 
    private String apType; 

} 
+0

@Shervin : 당신은 할 수 있지만, 좋은 생각은 아닙니다. 당신의 논리는 그것에 의존하지 말아야합니다. . –

+1

@ 파스칼 : 나는해야한다고 생각합니다. xhtml 쪽에서 나는 EL 표현식에서'instanceof'라고 말할 방법이 없다. (나는 생각한다). 그래서 나는 이것을 필요로할지 모른다. –

+1

@Shervin : 그렇게 말하면서 유감이지만 디자인에 큰 결함이있는 것 같지만 **보기 **는 판별 자 값에 의존해서는 안됩니다 (비즈니스 코드는 사실이지만 보기). –

5

처럼 뭔가를 할 수 있고, 내가가 입력 한 내용을 확인하기 위해 instanceof를 사용하지 않도록하려면 쿨러 될 것이다. 나는 그것이 쿨러있을 거라고 생각하지 않습니다 같은 (...)

을 할 수 있다면 쿨러 것, 이것은 나에게 instanceOf를 호출하는 것보다 더 나쁜 것 : 당신이 판별 값을 변경 어떤 이유로 경우, 당신의 코드를 깨뜨릴 것입니다.

유형을 확인해야하는 경우 instanceOf을 사용하십시오. discriminator를 사용하는 트릭이 더 좋게 만들지는 않을 것입니다. 그러면 코드의 안정성이 떨어집니다.

+1

+1 전적으로 동의합니다. 아마도이 리팩토링이 적용될 수 있습니다 : http://www.c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism –

+0

그러나 다음과 같이해야합니다 : 의사 코드 :'if (applicationProcess instanceof ApplicationProcessScheme)'. ApplicationProcessScheme도 일치 할 것이므로 ApplicationProcess와 비교할 수 없습니다. 그래서 코드는 'if (instanceType ApplicationProcessScheme) {//! instanceof}가 없으므로 {// 우리는 자식이 있습니다!'} –

+1

@Shervin : 예, 그렇게해야합니다. 이상적이라고 말하는 것이 아니며, 메타 데이터에 의존하는 것이 더 나쁠 것이라고 말하고 있습니다. 사실, 애쉬의 제안을 파헤칩니다. –

29

내가 도움이 될 수있는 몇 가지 경우를 상상할 수 있지만, 당신이 필요로하는 이유에도 불구하고, 당신이 당신의 추상 클래스에 만들 수를 같은 식

@Transient 
public String getDiscriminatorValue(){ 
    DiscriminatorValue val = this.getClass().getAnnotation(DiscriminatorValue.class); 

    return val == null ? null : val.value(); 
} 
+1

유스 케이스는 다음과 같을 수 있습니다. 유형 (국가, 언어, 성별, ...) 및 유형 다중 키 ("pl", "uk", "us"...) 및 값 "폴란드", "영국", ...). 어떤 타입은'@ OneToMany' 관계에서 사용될 수 있습니다. 국가는'@Entity Address'에서 사용될 수 있지만, 다른 타입은 데이터베이스를 조회 할 때만 사용될 수 있습니다. 그래서 : 기본 클래스는 대부분의 형식을 처리하지만 몇 가지 특정 형식은 고유 한 파생 클래스를 갖습니다. – Arjan

+0

나를 위해 받아 들여진 대답의 문제는 객관적인 사람이 방금 만들어졌지만 아직 저장되지 않았을 때, discriminator가 없다는 것이 었습니다. 데이터가 실제로 db에 유지되지 않는 테스트 케이스에서 나는 그 문제를 가지고있었습니다. 이것은 훌륭하게 작동했습니다. 감사합니다 –

+0

이것은 위대한 노력하고 있습니다. –

0

수식 주석을 사용할 수 있습니다. 당신은 최대 절전 모드를 사용하는 경우 , 당신은 this link에 따라 아래의 코드를 사용할 수 있습니다

private String theApType; 

@Formula("apType") 
String getTheApType() { 
    return theApType; 
} 

은 물론 당신은 쿼리에서 사용할 수있을 것입니다.