HibernateException: невозможно разрешить имя объекта из класса [java.lang.Boolean] ожидаемого экземпляра / подкласса
У меня есть субъект, который представляет root element
большого xml
файл, который был unmarshalled
от xml
в java
с помощью jaxb
, Я пытаюсь сохранить его, используя спящий режим EntityManager.persist(elementname)
, но это бросает HibernateException
, Сообщение об исключении просто утверждает, что не может разыграть Boolean
значение как определенный тип объекта.
Вот код, который выдает ошибку в строке 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;
}
Я загрузил урезанный рабочий проект Eclipse, который может помочь вам воссоздать эту проблему за пару минут. Это zip-файл, который вы можете скачать по этой ссылке. Чтобы воссоздать проблему на вашей машине, просто:
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`.
Затем он воссоздает ошибку. Затем вы можете просмотреть схему в schema.xsd
файл и урезанный XML в po.xml
файл.
Вы можете просмотреть структуру каталогов и увидеть расположение persistence.properties
, po.xml
, schema.xsd
, а также Main.java
на следующем снимке экрана ниже:
Я также получаю следующую трассировку стека:
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 ответ
Я полагаю, у вас здесь странное именование. У вас есть два свойства с именем id
а также setId
, За свойство JAXB генерировал два геттера (getXXX
) и, если указано "isSetter", чтобы проверить, установлено ли свойство, - полезно для примитивных типов. Этот isSetter называется isSetXXX
,
В этом случае ваш isSetter для setId
сталкивается с геттером для id
,
Исетьтер для setId
:
@Transient
public boolean isSetId() {
return (this.id!= null);
}
Добытчик для id
:
public II getSetId() {
return setId;
}
Заметка isSetId
против getSetId
, Это, вероятно, сводит Hibernate с ума, потому что он думает, что isSetId
является логическим получателем, тогда как он ожидает получателя энти.
Решение: переименуйте setId
свойство в вашей модели с помощью jaxb:property
в вашем файле привязок.