Hibernate:composite-id与key-many-to-one生成java.lang.stackoverflow错误

时间:2013-03-14 15:29:36

标签: java hibernate hibernate-mapping hbm

我一直在尝试使用hbm文件将以下表格映射到Hibernate:

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)        );

如您所见,它们共享相同的2字段主键 - 反过来,它也是从additional_info到info的外键。

这就是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 错误。 我一直在寻找和尝试不同的映射/替代组合,但没有成功 - 因为我没有太多的hibernate经验,它更像是狂野的猜测(现在大多数都在使用注释)。有人建议使用<id><generator>,但我找不到一个示例,其中两个字段用于链接一对一关系,即PK和FK。

我的类都是Serializable,并且也自动生成了equals和hashCode方法。

我也不明白为什么“关键多对一”。这应该是一对一的关系。我读到使用复合ID与这个密钥多对一不是一个好主意,但我没有实现一个有效的替代方案。

非常感谢任何见解。

非常感谢!

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)
...

2 个答案:

答案 0 :(得分:0)

如果定义双向引用,其中一个应该是惰性的,以避免StackOverflow

希望它对你有所帮助。

答案 1 :(得分:-2)

看看这里:

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

持久化类必须重写equals()和hashCode()以实现复合标识符相等性。它还必须实现Serializable。

不幸的是,这种方法意味着持久对象是它自己的标识符。除了对象本身之外没有方便的“句柄”。您必须先实例化持久化类本身的实例并填充其标识符属性,然后才能加载()与复合键关联的持久状态

希望它有所帮助。