在JPA(EclipseLink)的一个实体中将@Embeddable与@MappedSuperclass组合

Ste*_*vra 1 java jpa eclipselink

切换到EclipseLink 2.6.0(从2.5.2版开始)后,对于使用声明的域类

@MappedSuperclass
@Embeddable
public class ADomainClass { ... }
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [default] failed.
Internal Exception: java.lang.ClassCastException: org.eclipse.persistence.internal.jpa.metamodel.EmbeddableTypeImpl cannot be cast to org.eclipse.persistence.internal.jpa.metamodel.MappedSuperclassTypeImpl
    at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:231)
    ... 73 more
Caused by: java.lang.ClassCastException: org.eclipse.persistence.internal.jpa.metamodel.EmbeddableTypeImpl cannot be cast to org.eclipse.persistence.internal.jpa.metamodel.MappedSuperclassTypeImpl
    at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.preInitialize(MetamodelImpl.java:398)
    at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.<init>(MetamodelImpl.java:113)
    at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.<init>(MetamodelImpl.java:132)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.preInitializeMetamodel(EntityManagerSetupImpl.java:3755)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:2000)
    ... 71 more
Run Code Online (Sandbox Code Playgroud)

在新版本的EclipseLink中,这是否可能是不必要的回归?

(请注意,当我查看时,ClassCastException可以在同一堆栈帧中看到它,这是由我的类引起的ADomainClass。)

编辑:

我用例之间的继承Embeddables
我的超类ADomainClass(是@Embeddable)并被另一个@Embeddable类扩展了ASubtype,除非用注释超类@MappedSuperclass

根据http://en.wikibooks.org/wiki/Java_Persistence/Embeddables#Inheritance的说明EclipseLink / Toplink支持此JPA非标准功能。尽管应该使用DescriptorCustomizer和来实现这一目标InheritancePolicy。(而不是@MappedSuperclass?)

Pre*_*ric 6

我同意@Chris的评论,我不确定它对您有什么用,或者此类课程的目的是什么。@MappedSuperclass@Embeddable达到完全不同的目的。

@MappedSuperclass用于对所有实体使用的某些通用属性(例如id)或一些审核信息(例如createdAt和)进行分组createdBy。根据JPA 2.1规范:

[2.11.2]通常,此类映射超类的目的是定义多个实体类共有的状态和映射信息。

简而言之,映射的超类将由实体扩展。实体也可以扩展非实体类,但是在这种情况下,超类不会持久化,仅行为会被继承。此外,此类类的所有注释都将被忽略。

[2.11.3]非实体超类仅用于行为的继承。非实体超类的状态不是持久的。从非实体超类继承的任何状态在继承实体类中都是非持久的。实体管理器不管理这种非持久状态[23]。此类超类的所有注释都将被忽略。

@Embeddable用于将实体的某些属性分组/嵌入在单独的类中,也可以在其他实体中重用。可嵌入类的所有字段都映射到拥有实体中的列,除非@ElementCollection@CollectionTable用于存储它们。JPA规范未定义可嵌入对象的继承(尽管EclipseLink通过使用其本机API支持它)EclipseLink Doc。它们还可以包含到其他实体的映射(从JPA 2.0开始)。但是,它们并不打算由实体扩展。来自维基

通常,尝试在可嵌入对象和实体之间混合继承不是一个好主意,但是在某些情况下可能会起作用。
...
与可嵌入对象的父对象以外的实体与可嵌入对象的关系通常不是一个好主意,因为可嵌入对象是其父对象的私有相关部分。通常,关系应与可嵌入对象的父对象有关,而不应与可嵌入对象有关。否则,通常最好将可嵌入对象设为具有自己表的独立实体。