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 в вашем файле привязок.

Другие вопросы по тегам