Я пытался отобразить следующие таблицы в 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)
...