Java EclipseLink@MappedSuperclass和泛型

Java EclipseLink@MappedSuperclass和泛型,java,generics,eclipselink,mappedsuperclass,Java,Generics,Eclipselink,Mappedsuperclass,我在我的web应用程序中有几个域模型类,它们之间有层次关系。一个例子是用于对用户帖子进行分类的分层类别结构 有一些逻辑与这些类的层次性有关,这是常见的。因此,我尝试将逻辑移到一个泛型@MappedSuperclass注释的超类中 比如: @MappedSuperclass public abstract class HierarchicalBaseEntity<N extends HierarchicalBaseEntity<N>> extends Bas

我在我的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) { ...
}
它给出了以下例外情况:

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)
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)
为什么它抱怨非实体字符串

作为测试,我尝试删除泛型并将父字段定义为:

private HierarchicalBaseEntity parent;
没有泛型,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.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)
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)

True HierarchycalBaseEntity在这两种情况下都不是实体,而是@MappedSuperclass。。但是,有没有一种方法可以用泛型或其他方法来实现这一点?在@MappedSuperclass中,似乎不能有一个字段引用它的子类。

问题是,当使用泛型作为关系的字段类型时,EclipseLink直到运行时检查实际实例时才知道目标类型是什么。因此,必须在运行时动态创建映射,这是不受支持的


您可以继续使用泛型超类,但这需要将字段移动到实体,在实体中定义类型,然后为那些返回泛型方法将调用转换为泛型类型的对象的字段定义抽象内部getter/setter。很复杂,但它允许使用通用的MappedSuperclass。

我想我已经迟到了,但是寻找这个问题答案的人(像我一样)应该看看这个:

在持久关系中支持泛型类型的另一个提供程序是。OpenJPA假设泛型类型字段是一个持久类型,并使用(OpenJPA特有的)@type注释进行注释


这个@Type注释充当OpenJPA映射引擎的占位符,并保存一个映射,其中引用是运行时实例的持久标识。很多年前,我写了一篇文章;我在这里再次引用它并不是为了自我提升,而是希望它能为您指明一些支持泛型树的途径,而不必将具体的类型信息向下推到类型层次结构中(从而失去基于泛型的类型模型的本质)。

这看起来有点类似(但相关问题已经解决)。你能试试其他供应商吗?嗨,戈登,谢谢你的回答。我将尝试您的建议,将字段放入子类中。。我能看出它是如何工作的。目前,我有一个HierarchyCalentity接口和一个静态“helper”类,其中包含逻辑。工作,但它不像我想要的那么干净。我想知道@AssociationOverride是否可以用于以某种方式重新定义关联。不幸的是,在这种情况下,问题在于属性类型@AssociationOverrides用于更改数据库信息,但没有用于指定目标类型的属性。您好,Gordon,我再也找不到比您所建议的更干净的解决方案了,它可以为带有抽象getter的公共逻辑实现超类。所以我投你一票。顺便说一句,你知道这在任何其他JPA实现中是否可行,或者它是JPA规范的一部分吗?我不知道是否有其他提供商支持这一点,但我对此表示怀疑。该规范没有特别提到通用属性类型,但警告读者覆盖映射元数据是不可移植的。