I have problem with my entity.
Everything works fine until I've changed classes inheritance from:
GenericModel -> Insurance -> Doctor
GenericModel -> Insurance -> Nurse
to:
GenericModel -> Insurance -> Liability > Doctor
GenericModel -> Insurance -> Liability > Nurse
GenericModel -> Insurance -> Contract
What have I done:
Liability
releated elements to new Liability
class. Contract
class, which inheritade from Insurance
class. Liability
from Insurance
class. Here are my entities with new structure:
@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;
}
}
Everything looks ok for me, but unfortunately I am getting an errors:
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 is full stack trace:
! @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
If it somehow helps, here is my previous post about Inheritance with Generics, which draws me to this issue.
Perhaps there is some issue with my contructors. I dont know, maybe I Should somewhere declare parameter typed constructor?
Please help me.
@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);
}
package org.fastnate.data.util;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
/**
* Helper for inspection of classes.
*
* @author Tobias Liefke
*/
public final class ClassUtil {
private static <I> Type getActualTypeArgument(final Class<? extends I> instanceClass, final Class<I> superClass,
final int argumentIndex) {
final List<Type> parents = new ArrayList<>();
parents.add(instanceClass.getGenericSuperclass());
parents.addAll(Arrays.asList(instanceClass.getGenericInterfaces()));
for (final Type parentType : parents) {
final Class<?> parentClass = parentType instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) parentType)
.getRawType() : (Class<?>) parentType;
// First check if we found the super class or interface
if (superClass.equals(parentClass)) {
// We found the requested super class - use the binding
return ((ParameterizedType) parentType).getActualTypeArguments()[argumentIndex];
} else if (parentClass != null && superClass.isAssignableFrom(parentClass)) {
// Else step up
final Type type = getActualTypeArgument(parentClass.asSubclass(superClass), superClass, argumentIndex);
if (type instanceof Class) {
return type;
} else if (type instanceof TypeVariable) {
return ((ParameterizedType) parentType).getActualTypeArguments()[Arrays.asList(
parentClass.getTypeParameters()).indexOf(type)];
}
}
}
return null;
}
/**
* Resolves the actual binding of a generic type that was specified in a superclass and bound in a subclass.
*
* @param instanceClass
* the implementing class
* @param superClass
* the superclass or interface which specifies the generic type variable
* @param argumentIndex
* the index of the type variable in the superclass definition (0 = the first type variable)
* @return the bound class for the variable in instanceClass
*/
public static <T, I> Class<T> getActualTypeBinding(final Class<? extends I> instanceClass,
final Class<I> superClass, final int argumentIndex) {
Type type = getActualTypeArgument(instanceClass, superClass, argumentIndex);
if (type instanceof TypeVariable<?>) {
type = ((TypeVariable<?>) type).getBounds()[0];
}
if (type instanceof ParameterizedType) {
type = ((ParameterizedType) type).getRawType();
}
if (type instanceof Class<?>) {
return (Class<T>) type;
}
throw new NoSuchElementException("Can't find binding for the " + argumentIndex + ". argument of " + superClass
+ " in " + instanceClass);
}
private ClassUtil() {
// Helper class
}
}
This has nothing to do with JPA.
If you look at the 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]
And it references this line:
entityClass = ((Class) ((Class) genericSuperclass_.getActualTypeArguments()[0]));
The actual type argument of Insurance
ist not an explicit class, but a type variable. Sou you can't cast it to a class.
If you would like to find the actual binding for a parameter of your class - I've created that for Fastnate : ClassUtil.getActualTypeBinding :
ClassUtil.getActualTypeBinding(getClass(), GenericModel.class, 0);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.