Hibernate:StackOverflowException记录ManyToMany关联

时间:2014-09-19 16:20:29

标签: java hibernate jpa many-to-many stack-overflow

org.hibernate.loader上激活调试日志记录后,当hibernate尝试记录类似"加载集合[com.Bar#42]"

时,我有一个StackOverflowException

重复的堆栈就是这个:

at com.Quz.toString(Quz.java:120)
at org.hibernate.type.descriptor.java.AbstractTypeDescriptor.extractLoggableRepresentation(AbstractTypeDescriptor.java:109)
at org.hibernate.type.AbstractStandardBasicType.toLoggableString(AbstractStandardBasicType.java:291)
at org.hibernate.pretty.MessageHelper.collectionInfoString(MessageHelper.java:307)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2158)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:62)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:627)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1863)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:369)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentBag.toString(PersistentBag.java:506)
at java.lang.String.valueOf(String.java:2854)
at java.lang.StringBuilder.append(StringBuilder.java:128)
at com.Quz.toString(Quz.java:120)

通常,我在持有集合的对象上执行toString,hibernate尝试记录集合加载,在对象上调用toString等等。

它附加一个单向的@ManyToMany,如下所示:

@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "fooId", "barId" }))
public class Quz {
    @Id
    @GeneratedValue
    protected Long id;

    protected String fooId;

    @ManyToOne
    @JoinColumn(name="barId")
    protected Bar bar;

    @ManyToMany
    @JoinTable(name = "quz_fum", joinColumns = {
            @JoinColumn(name = "fooId", referencedColumnName = "fooId"),
            @JoinColumn(name = "barId", referencedColumnName = "barId") },
                                 inverseJoinColumns = {
            @JoinColumn(name = "fumId", referencedColumnName = "fumId") })
    protected List<Fum>  fums;
}

当joinColumns由主键(hibernate log only its id)组成时,它工作,所以我认为问题是由于我在JoinTable中有非主列的事实(而hibernate尝试记录整个对象) )。

这是一个错误还是禁止像这样的JoinTable?

由于

我正在使用hibernate版本3.6.0.Final。

编辑:

toString方法中没有错误。我很有信心。 首先,我们可以在堆栈中没有其他hibernate的递归调用之间的任何中间。 toString调用hibernate,调用相同的toString。 在关闭休眠日志记录时,toString运行良好。当我打开它时会出现异常。 3我已经调试了足够长的时间来找到这个问题:hibernate调用对象本身的toString而不是其具有特定ManyToMany设置的id。

我原来的问题是关于那个设置:是允许的吗?

1 个答案:

答案 0 :(得分:2)

您似乎有类似以下内容:

class Foo {

    Collection<Bar> bars;

    @Override
    public String toString() {
        return "Foo{" + "bars=" + bars + '}';
    }

}

class Bar {

    Collection<Foo> foos;

    @Override
    public String toString() {
        return "Bar{" + "foos=" + foos + '}';
    }

}

现在,当我拨打bar.toStringfoo.toString之一时,我会陷入无限循环:

bar.toString
foos.toString
foo.toString
bars.toString
bar.toString

你根本不能拥有这样的toString方法 - 你需要决定一方打印该集合而另一方不这样做。