2013-03-14 1 views
1

Я пытался отобразить следующие таблицы в Hibernate с HBM файлы:Hibernate: композиционно-идентификатор с ошибкой java.lang.stackoverflow ключ-много-к-одному генерирующего

CREATE TABLE 
    additional_info 
    (
     info_id SMALLINT, 
     book_id INT, 
     desc VARCHAR(32) NULL, 
     CONSTRAINT additional_info_pk PRIMARY KEY (info_id, book_id), 
     CONSTRAINT additional_info_fk FOREIGN KEY (info_id, book_id) REFERENCES info (id, book_id) 
    ); 

CREATE TABLE 
    info 
    (
     id SMALLINT, 
     book_id INT, 
     item_name VARCHAR(32), 
     CONSTRAINT pk_info PRIMARY KEY (id, book_id), 
     CONSTRAINT fk_info FOREIGN KEY (book_id) REFERENCES book (book_id)  ); 

Как вы видите, они оба используют один и тот же первичный ключ с двумя полями, который, в свою очередь, также является внешним ключом от дополнительного_инфо к информации.

Это как hibernateTools определяется соотношением (ADDITIONAL_INFO HBM):

<composite-id name="id" class="AdditionalInfoId"> 
    <key-many-to-one name="info" class="Info"> 
     <column name="info_id" /> 
     <column name="book_id" /> 
    </key-many-to-one> 
</composite-id> 

И INfO в HBM:

<one-to-one name="additionalInfo" class="AdditionalInfo"></one-to-one> 

Используя этот подход, я постоянно получаю java.lang.stackoverflow ошибка. Я искал и пробовал разные комбинации отображений/альтернатив, но безуспешно - так как у меня нет большого опыта работы в спящем режиме, это больше похоже на дикое угадывание (и большинство из них сейчас используют аннотации). Некоторые предлагают использовать <id> и <generator>, но я не смог найти пример с двумя полями, которые используются для связывания отношения один к одному, являясь как PK, так и FK.

Мои классы являются Serializable и имеют методы equals и hashCode, сгенерированные автоматически.

Я также не понимаю, почему «ключ-много-к-одному». Это должно быть отношение «один к одному». Я читал, что это не очень хорошая идея с использованием составного идентификатора с этим ключом-много-к-одному, но я не смог реализовать альтернативу, которая работает.

Любое понимание было бы весьма полезным.

Большое спасибо!

PS: кусок трассировки стека:

java.lang.StackOverflowError 
    at java.lang.Integer.equals(Integer.java:747) 
    at org.hibernate.util.EqualsHelper.equals(EqualsHelper.java:10) 
    at org.hibernate.type.NullableType.isEqual(NullableType.java:214) 
    at org.hibernate.type.NullableType.isEqual(NullableType.java:210) 
    at org.hibernate.type.AbstractType.isEqual(AbstractType.java:116) 
    at org.hibernate.engine.EntityKey.equals(EntityKey.java:97) 
    at java.util.HashMap.get(HashMap.java:305) 
    at org.hibernate.engine.StatefulPersistenceContext.getEntity(StatefulPersistenceContext.java:322) 
    at org.hibernate.impl.SessionImpl.getEntityUsingInterceptor(SessionImpl.java:478) 
    at org.hibernate.event.def.DefaultLoadEventListener.loadFromSessionCache(DefaultLoadEventListener.java:436) 
    at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:338) 
    at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139) 
    at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:195) 
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103) 
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878) 
    at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:846) 
    at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:557) 
... 

ответ

0

Если определить двунаправленные ссылки один из них должен быть ленивым, чтобы избежать StackOverflow.

Надеюсь, это поможет вам.

-2

Посмотрите здесь:

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/mapping.html

Упорное класс должен переопределить равных() и хэш-код() для выполнения составного равенства идентификатора. Он также должен реализовать Serializable.

К сожалению, этот подход означает, что постоянным объектом является его собственный идентификатор. Нет удобной «рукоятки», кроме самого объекта. Вы должны создать экземпляр самого стойкого класса и заполнить его свойства идентификатора, прежде чем вы сможете загрузить() постоянное состояние, связанное с составным ключом

надеюсь, что это поможет.