问题
I have an entity that represents the root element
of a large xml
file that was unmarshalled
from xml
to java
using jaxb
. I am trying to persist it using hibernate EntityManager.persist(elementname)
, but it is throwing a HibernateException
. The exception message simply states that it cannot cast a Boolean
value as a specific object type.
Here is the code that is throwing the error at the line persist(cd)
:
public Long saveToDatabase(ClinicalDocument cd){
Long id = null;
try{
final EntityManager saveManager = entityManagerFactory.createEntityManager();
saveManager.getTransaction().begin();
saveManager.persist(cd);
saveManager.getTransaction().commit();
saveManager.close();
//After the object is saved, we can get the generated id:
id = cd.getHjid();
}catch(HibernateException sqle){sqle.printStackTrace();}
return id;
}
I uploaded a stripped down working eclipse project that can enable you to recreate this problem in a couple minutes. It is a zip file that you can download from this link. To recreate the problem on your machine, just:
1.) unzip the folder
2.) import the folder into eclipse as an existing project
3.) change `persistence.properties` to include a valid username, password, and database name on your machine
4.) then right click on `Main.java` and choose `Run As..Java Application`.
It will then recreate the error. You can then review the schema in the schema.xsd
file and the stripped down xml in the po.xml
file.
You can view the directory structure and see the locations of persistence.properties
, po.xml
, schema.xsd
, and Main.java
in the following screen shot below:
I also get the following stack trace:
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.HibernateException: Unable to resolve entity name from Class [java.lang.Boolean] expected instance/subclass of [org.jvnet.hyperjaxb3.ejb.tests.pocustomized.II]
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1154)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:678)
at productionmain.DataFunctions.saveToDatabase(DataFunctions.java:265)
at productionmain.Main.main(Main.java:21)
Caused by: org.hibernate.HibernateException: Unable to resolve entity name from Class [java.lang.Boolean] expected instance/subclass of [org.jvnet.hyperjaxb3.ejb.tests.pocustomized.II]
at org.hibernate.tuple.entity.PojoEntityTuplizer.determineConcreteSubclassEntityName(PojoEntityTuplizer.java:360)
at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassEntityPersister(AbstractEntityPersister.java:3941)
at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1494)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:202)
at org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:531)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:102)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:799)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:791)
at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:48)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:450)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:282)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:808)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:782)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:786)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:672)
... 2 more
回答1:
I believe you have a weird naming colission here. You have two properties named id
and setId
. Per property, JAXB generated two a getter (getXXX
) and, if instructed "isSetter" to check if the property is set - useful for primitive types. This "isSetter" is named isSetXXX
.
In this case your isSetter for setId
collides with the getter for id
.
Issetter for setId
:
@Transient
public boolean isSetId() {
return (this.id!= null);
}
Getter for id
:
public II getSetId() {
return setId;
}
Note isSetId
vs. getSetId
. This probably makes Hibernate crazy because it thinks that isSetId
is a boolean getter whereas it expects an enity getter.
Solution: rename the setId
property in you model using jaxb:property
in your bindings file.
来源:https://stackoverflow.com/questions/26517573/hibernateexception-unable-to-resolve-entity-name-from-class-java-lang-boolean