Tim*_*m P 6 java generics eclipselink mappedsuperclass
我的Web应用程序中有一些域模型类,它们与自己有层次关系.一个示例是用于对用户发布进行分类的分层类别结构.
有一些逻辑与这些类的层次性有关,这是常见的.所以我试图将逻辑移到一个通用的@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) { ...
}
Run Code Online (Sandbox Code Playgroud)
然后子类扩展HierarchicalBaseEntity,将自己作为泛型类型N:
@Entity
public class CategoryBean extends HierarchicalBaseEntity<CategoryBean> {
Run Code Online (Sandbox Code Playgroud)
在Java中,这一切都非常干净.但不幸的是,EclipseLink似乎不喜欢通用的"父"字段:
private N parent;
Run Code Online (Sandbox Code Playgroud)
它给出了以下例外:
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)
Run Code Online (Sandbox Code Playgroud)
为什么抱怨非实体字符串?
作为测试,我尝试删除泛型,并将父字段定义为:
private HierarchicalBaseEntity parent;
Run Code Online (Sandbox Code Playgroud)
没有泛型,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)
Run Code Online (Sandbox Code Playgroud)
True HierarchicalBaseEntity在任何一种情况下都不是实体,是@MappedSuperclass ..但有没有办法用泛型或其他方式做到这一点?看来你的@MappedSuperclass中没有一个字段可以引用它的一个子类.
问题是,当使用泛型作为关系的字段类型时,EclipseLink 无法知道目标类型是什么,直到运行时检查实际实例。因此映射必须在运行时动态创建,而这是不受支持的。
您可以继续使用泛型超类,但这需要将字段移动到实体,在那里它们将定义类型,然后为那些返回对象的字段提供抽象的内部 getter/setter,泛型方法将调用转换为泛型类型。令人费解,但它允许通用 MappedSuperclass。
归档时间: |
|
查看次数: |
4326 次 |
最近记录: |