2010-08-08 5 views
5

웹 응용 프로그램에 계층 적 관계가있는 도메인 모델 클래스가 몇 개 있습니다. 한 예로 사용자 게시를 분류하는 데 사용되는 계층 적 카테고리 구조가 있습니다.EclipseLink @MappedSuperclass 및 generics

일반적으로 이러한 클래스의 계층 적 특성과 관련된 논리가 있습니다. 그래서 로직을 일반 @MappedSuperclass 주석이 달린 수퍼 클래스로 옮기려고했습니다. 같은

뭔가 :

@MappedSuperclass 
public abstract class HierarchicalBaseEntity<N extends HierarchicalBaseEntity<N>> extends BaseEntity { 

@ManyToOne(optional=true) 
@JoinColumn(name="parent") 
private N parent; 
private int depth; 

public N getParent() { ... 
public void setParent(N newParent) { ... 

public boolean isRoot() { ... 
public int getDepth() { ... 

public boolean isDescendantOf(N ancestor) { ... 
public static <N extends HierarchicalBaseEntity<N>> N getCommonAncestor(N a, N b) { ... 
public static <N extends HierarchicalBaseEntity<N>> Collection<N> reduceToCommonAncestors(Collection<N> entities) { ... 
} 

서브 클래스는 다음 제네릭 형식 N으로 자신을주는 HierarchicalBaseEntity을 확장 :

@Entity 
public class CategoryBean extends HierarchicalBaseEntity<CategoryBean> { 

자바에서이 모든 아주 깨끗하게 밖으로 작동합니다.

private N parent; 

그것은 다음과 같은 예외가 있습니다 :

Caused by: Exception [EclipseLink-7250] (Eclipse Persistence Services - 2.1.0.v20100614-r7608): org.eclipse.persistence.exceptions.ValidationException 
Exception Description: [class net.timp.yaase.core.model.HierarchicalBaseEntity] uses a non-entity [class java.lang.String] as target entity in the relationship attribute [field parent]. 
at org.eclipse.persistence.exceptions.ValidationException.nonEntityTargetInRelationship(ValidationException.java:1341) 
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.RelationshipAccessor.getReferenceDescriptor(RelationshipAccessor.java:416) 
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOneToOneForeignKeyRelationship(ObjectAccessor.java:609) 
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOwningMappingKeys(ObjectAccessor.java:678) 
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToOneAccessor.process(ManyToOneAccessor.java:107) 

가 왜 비 엔티티 문자열에 대해 불평된다 그러나 불행하게도는 EclipseLink가 아니라 일반적인 '부모'란을 좋아하는 것입니까? 을

Caused by: Exception [EclipseLink-7250] (Eclipse Persistence Services - 2.1.0.v20100614-r7608): org.eclipse.persistence.exceptions.ValidationException 
Exception Description: [class net.timp.yaase.core.model.OnymBean] uses a non-entity [class net.timp.yaase.core.model.HierarchicalBaseEntity] as target entity in the relationship attribute [field parent]. 
at org.eclipse.persistence.exceptions.ValidationException.nonEntityTargetInRelationship(ValidationException.java:1341) 
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.RelationshipAccessor.getReferenceDescriptor(RelationshipAccessor.java:416) 
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOneToOneForeignKeyRelationship(ObjectAccessor.java:609) 
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOwningMappingKeys(ObjectAccessor.java:678) 
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToOneAccessor.process(ManyToOneAccessor.java:107) 

진정한 HierarchicalBaseEntity이 아니 : 제네릭없이

private HierarchicalBaseEntity parent; 

은 EclipseLink가이 예외를했다 : 나는 시도했다 테스트 제네릭을 제거하고 단지로 상위 필드가 정의 필요로

어느 경우 든 엔티티는 @MappedSuperclass입니다.하지만 제네릭이나 다른 방법으로이 작업을 수행 할 수있는 방법이 있습니까? @MappedSuperclass에 하위 클래스 중 하나를 참조하는 필드를 가질 수없는 것 같습니다.

+0

http://forums.sun.com/thread.jspa?threadID=5268944와 비슷한 모양입니다 (단, 관련 문제는 수정 됨). 다른 공급자와 함께 시도해 볼 수 있습니까? –

답변

3

관계의 필드 유형으로 Generics를 사용하는 경우 실제 인스턴스를 검사 할 때 런타임까지 대상 유형이 무엇인지 알 수없는 것이 문제입니다. 따라서 매핑은 런타임에 동적으로 생성되어야하며 이는 지원되지 않습니다.

일반 SuperClass를 계속 사용할 수 있지만 정의 된 유형이있는 엔터티로 필드를 이동 한 다음 일반 메서드가 캐스팅을 호출하는 Object를 반환하는 필드에 대한 추상 내부 getter/setter를 가져야합니다. 제네릭 유형. 뒤얽혀 있지만 Generic MappedSuperclass를 허용합니다.

+0

안녕하세요 고든, 답변 해 주셔서 감사합니다. 필드를 서브 클래스에 두는 것에 대한 여러분의 제안을 시도 할 것입니다. 어떻게 작동하는지 볼 수 있습니다. 현재 HierarchicalEntity 인터페이스와 Works의 논리가있는 정적 '도우미'클래스가 있지만 마음에 들지 않는 깨끗한 것은 아닙니다. @AssociationOverride가 어떤 식 으로든 연결을 재정의하는 데 사용될 수 있는지 궁금합니다. –

+0

불행히도이 경우 문제는 속성 유형과 관련이 있습니다. @AssociationOverrides는 데이터베이스 정보를 변경하는 데 사용되지만 대상 유형을 지정하는 속성이 없습니다. –

+0

안녕하세요 다시 Gordon, 나는 당신이 추상적 인 getters와 일반적인 논리에 대한 수퍼 클래스를 구현하기 위해 제안한 것보다 깨끗한 솔루션을 찾을 수 없습니다. 그래서 내 표를 얻는다. BTW. 다른 JPA 구현에서 이것이 가능한지 또는 JPA 스펙의 일부인지 여부를 알고 있습니까? –

-1

지속적인 관계에서 제네릭 형식을 지원하는 다른 공급자가 OpenJPA입니다 . OpenJPA가 가정한다는 것은 제네릭 형식 필드가 영구 형식이고 (OpenJPA 관련) @Type 주석을 사용하여 주석을 달았습니다.

이 @Type 어노테이션은 OpenJPA 매핑 엔진의 자리 표시 자 역할을하며 참조가 런타임 인스턴스의 지속적인 ID 인 매핑을 보유합니다. 몇 년 전에, 나는 blog를 썼다. 나는 여기에 자기 홍보를위한 것이 아니라 그것을 다시 인용하지만, 유형 정보를 구체적인 유형 정보를 사용하여 일반 유형의 모델을 본질적으로 잃지 않고도 일반 트리를 지원할 수있는 길을 제시하기를 바란다.).