具有泛型和多级继承的JPA。设置单表策略。 org.hibernate.MappingException:无法获取构造函数

时间:2015-07-22 09:57:59

标签: java hibernate generics jpa inheritance

我的实体有问题。

一切正常,直到我改变了类继承:

var changeImage  = "https://cdn4.iconfinder.com/data/icons/geomicons/32/672366-x-128.png";
var originaImage = "https://cdn3.iconfinder.com/data/icons/lightly-icons/30/652841-menu-120.png";
$('#menu-cross').on('click',function(){
    $(this).fadeOut(500,function(){
      if($(this).attr('data-changed')=='true')
      {
          $(this).attr('src', originaImage).attr('data-changed','false');    
      }
      else
      {
           $(this).attr('src', changeImage).attr('data-changed','true');       
      }
    }).fadeIn(500);
 });

为:

GenericModel -> Insurance -> Doctor
GenericModel -> Insurance -> Nurse

我做了什么:

  • 我已将一些GenericModel -> Insurance -> Liability > Doctor GenericModel -> Insurance -> Liability > Nurse GenericModel -> Insurance -> Contract 个相关元素外部化为新的Liability类。
  • 我已添加Liability类,该类继承自Contract类。
  • 我从Insurance课程中获取了与Liability相关的一些功能/元素。

以下是具有新结构的实体:

Insurance
@MappedSuperclass
public abstract class GenericModel<T extends GenericModel> {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long id;
    @Transient protected Class<T> entityClass;
    public GenericModel() {
        Class obtainedClass = getClass();
        Type genericSuperclass = null;
        for(;;) {
            genericSuperclass = obtainedClass.getGenericSuperclass();
            if(genericSuperclass instanceof ParameterizedType) {
                break;
            }
            obtainedClass = obtainedClass.getSuperclass();
        }
        ParameterizedType genericSuperclass_ = (ParameterizedType) genericSuperclass;
        entityClass = ((Class) ((Class) genericSuperclass_.getActualTypeArguments()[0]));
    }
}
@Entity
@DiscriminatorColumn(name="type")
@DiscriminatorValue(value="A")
@Table(name="mi__Insurance")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Insurance<T extends Insurance> extends GenericModel<T> {
    public Insurance() {
        super();
        this.status  = Status.STARTED.getId();
        this.statusDescription = Status.getDescriptionBy(this.status);
        this.statusColor = Status.getColorBy(status);
        this.statusAction = Status.getActionBy(status);
        this.progress = 0;
        this.policyHolder_Answer = null;
        this.policyHolder = 1;
        this.filledParts = 1;
        this.totalParts = 2;
    }
}
@Entity
@DiscriminatorValue(value="C")
public class Contract extends Insurance<Contract> {
    public Contract() {
        super();
        this.setColor("danger");
        this.setIcon();
        this.setFormUrl();
    }
}
@Entity
@DiscriminatorValue(value="L")
public class Liability extends Insurance<Liability> {
    public Liability() {
        super();
        this.legal_Answer = null;
        this.freely = 0;
        this.mandatory = 0;
        this.hiv = 0;
        this.legal = 0;

    }
}

一切看起来都不错,但不幸的是我收到了错误:

@Entity
@DiscriminatorValue(value="D")
public class Doctor extends Liability {

    public Doctor() {
        super();
        this.setType(Type.DOCTOR);
        this.setColor("success");
        this.setIcon();
        this.setFormUrl();
        this.hiv_Answer = null;
    }
}

这是完整的堆栈跟踪:

play.api.UnexpectedException: Unexpected exception[PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build EntityManagerFactory]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build EntityManagerFactory
Caused by: org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
Caused by: org.hibernate.InstantiationException: could not instantiate test objectmyInsurance.models.Insurance
Caused by: java.lang.reflect.InvocationTargetException: null
Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class

如果它有所帮助,here是我之前关于遗传与泛型的帖子,它引导我解决这个问题。

也许我的结构有一些问题。我不知道,也许我应该在某处声明参数类型构造函数?

请帮帮我。

编辑 - 工作解决方案

! @6mped6a12 - Internal server error, for (GET) [/] ->

play.api.UnexpectedException: Unexpected exception[PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build EntityManagerFactory]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:148) ~[play_2.10.jar:2.2.6]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:112) ~[play_2.10.jar:2.2.6]
        at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:112) ~[play_2.10.jar:2.2.6]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:110) ~[play_2.10.jar:2.2.6]
        at scala.util.Success.flatMap(Try.scala:200) ~[scala-library.jar:na]
        at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:110) ~[play_2.10.jar:2.2.6]
        at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:102) ~[play_2.10.jar:2.2.6]
        at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library.jar:na]
        at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) ~[scala-library.jar:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build EntityManagerFactory
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:890) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63) ~[hibernate-jpa-2.0-api.jar:1.0.1.Final]
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47) ~[hibernate-jpa-2.0-api.jar:1.0.1.Final]
        at play.db.jpa.JPAPlugin.onStart(JPAPlugin.java:35) ~[play-java-jpa_2.10.jar:2.2.6]
        at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at scala.collection.immutable.List.foreach(List.scala:318) ~[scala-library.jar:na]
        at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at play.api.Play$$anonfun$start$1.apply(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at play.api.Play$$anonfun$start$1.apply(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10.jar:2.2.6]
        at play.api.Play$.start(Play.scala:87) ~[play_2.10.jar:2.2.6]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:139) ~[play_2.10.jar:2.2.6]
        ... 14 common frames omitted
Caused by: org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
        at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:185) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:385) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1742) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        ... 28 common frames omitted
Caused by: org.hibernate.InstantiationException: could not instantiate test objectmyInsurance.models.Insurance
        at org.hibernate.engine.internal.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:49) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.engine.internal.UnsavedValueFactory.getUnsavedIdentifierValue(UnsavedValueFactory.java:68) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:75) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:145) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:507) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:146) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.7.0_80]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) ~[na:1.7.0_80]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_80]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[na:1.7.0_80]
        at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        ... 33 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.7.0_80]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) ~[na:1.7.0_80]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_80]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[na:1.7.0_80]
        at org.hibernate.engine.internal.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:46) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        ... 43 common frames omitted
Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
        at generic.models.GenericModel.<init>(GenericModel.java:51) ~[na:na]
        at myInsurance.models.Insurance.<init>(Insurance.java:151) ~[na:na]
        ... 48 common frames omitted
@MappedSuperclass
public abstract class GenericModel<T extends GenericModel> {
    /**
     * Works for nested/inner classes and Typed Parametered Classes
     */
    public GenericModel() {
        Class obtainedClass = getClass();
        Type genericSuperclass = null;
        for(;;) {
            genericSuperclass = obtainedClass.getGenericSuperclass();
            if(genericSuperclass instanceof ParameterizedType) {
                break;
            }
            obtainedClass = obtainedClass.getSuperclass();
        }
        ParameterizedType genericSuperclass_ = (ParameterizedType) genericSuperclass;
        try {
            entityClass = ((Class) ((Class) genericSuperclass_.getActualTypeArguments()[0]));
        } catch (ClassCastException e) {
            entityClass = guessEntityClassFromTypeParametersClassTypedArgument();
        }
    }
}   
/**
 * Use in case of extending GenericModel<ExtendingClass<TypeArgument>>
 * Use if passed into GenericModel TypeParameter which isn't actual class, but Class with TypedParameter
 * @return 
 */ 
public Class<T> guessEntityClassFromTypeParametersClassTypedArgument() {
    return ClassUtil.getActualTypeBinding(getClass(), GenericModel.class, 0);
}

1 个答案:

答案 0 :(得分:1)

这与JPA无关。

如果你看一下stacktrace:

Caused by: java.lang.ClassCastException: 
    sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
        at generic.models.GenericModel.<init>(GenericModel.java:51) ~[na:na]

它引用了这一行:

entityClass = ((Class) ((Class) genericSuperclass_.getActualTypeArguments()[0]));

Insurance的实际类型参数不是显式类,而是类型变量。你不能把它扔到课堂上。

如果您想查找班级参数的实际绑定,我已为Fastnate创建了ClassUtil.getActualTypeBinding

ClassUtil.getActualTypeBinding(getClass(), GenericModel.class, 0);
相关问题