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) { ...
}

Затем подклассы расширяют HierarchicalBaseEntity, предоставляя себя в качестве универсального типа N:

@Entity
public class CategoryBean extends HierarchicalBaseEntity<CategoryBean> {

В Java все это работает довольно чисто. Но, к сожалению, EclipseLink, похоже, не нравится родовое поле родителя:

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)

Почему он жалуется на не-сущностную строку?

В качестве теста я пытался удалить Обобщения и просто наличие родительского поля, определенного как:

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.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 HierarchicalBaseEntity не является Entity в любом случае, это @MappedSuperclass ... но есть ли способ сделать это с дженерики или иначе? Кажется, в вашем @MappedSuperclass не может быть поля, которое ссылается на один из его подклассов.

6
задан Jin Kwon 20 September 2018 в 01:37
поделиться