Ich habe einige Domain Model Klassen in meiner Web App, die eine hierarchische Beziehung zu sich selbst haben. Ein Beispiel hierfür ist die hierarchische Kategoriestruktur, die zur Klassifizierung von Benutzerbuchungen verwendet wird.EclipseLink @MappedSuperclass und Generics
Es gibt einige Logik in Bezug auf die hierarchische Natur dieser Klassen, die häufig ist. Also habe ich versucht, die Logik in eine generische @MappedSuperclass Annotated Superklasse zu verschieben.
Etwas wie:
@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) { ...
}
Die Unterklassen erstrecken sich dann HierarchicalBaseEntity sich als gattungs N geben:
@Entity
public class CategoryBean extends HierarchicalBaseEntity<CategoryBean> {
In Java funktioniert das alles ganz sauber aus. Aber leider ist Eclipse scheint nicht die generische ‚Eltern‘ Feld zu mögen:
private N parent;
Es gibt folgende Ausnahme:
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)
Warum ist es beschweren sich über eine Nicht-Einheit String?
Als Test habe ich versucht, die Generika zu entfernen und mit nur dem übergeordneten Feld wie folgt definiert:
private HierarchicalBaseEntity parent;
Ohne Generika, Eclipse diese Ausnahme gab:
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)
Wahren HierarchicalBaseEntity seine keine Entität ist in jedem Fall eine @MappedSuperclass .. aber gibt es eine Möglichkeit, dies mit Generika oder anderweitig zu tun? Es scheint, dass Sie kein Feld in Ihrer @MappedSuperclass haben können, das auf eine seiner Unterklassen verweist.
Das sieht irgendwie ähnlich * zu http://forums.sun.com/thread.jspa?threadID=5268944 (aber das damit verbundene Problem ist behoben). Könnten Sie es mit einem anderen Anbieter versuchen? –