Hibernate:StackOverflowException记录ManyToMany关联 [英] Hibernate : StackOverflowException logging ManyToMany association

查看:127
本文介绍了Hibernate:StackOverflowException记录ManyToMany关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

org.hibernate.loader上激活调试日志记录后,当hibernate尝试记录诸如加载集合[com.Bar#42]"之类的内容时,我有一个StackOverflowException

After activating debug logging on org.hibernate.loader, i have a StackOverflowException when hibernate tries to log something like "loading collection [com.Bar#42]"

重复的堆栈就是这个:

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,依此类推.

Typically, i do a toString on the object holding the collection, hibernate tries to log the collection loading, which call toString on the object and so on.

它像这样附加在单向@ManyToMany上:

It appends on a unidirectional @ManyToMany like this :

@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由主键组成(休眠日志仅记录其ID)时,它可以工作,所以我认为问题是由以下事实引起的:我在JoinTable中具有非主列(并且hibernate尝试记录整个对象).

It works when the joinColumns is composed of the primary key (hibernate log only its id), so i think the problem is caused by that fact that i have non primary columns in my JoinTable (and hibernate tries to log the entire object).

是Bug还是被禁止拥有这样的JoinTable?

Is it a bug or is it a forbidden to have a JoinTable like that?

谢谢

我正在使用休眠版本3.6.0.Final.

I'm using hibernate version 3.6.0.Final.

toString方法z没有问题.我确定. 首先,我们可以在堆栈中的其他休眠的递归调用之间没有任何中间对象. toString调用休眠方式,该休眠方式调用相同的toString. 第二,当休眠日志记录关闭时,toString可以很好地工作.那是我打开它时出现的异常. 第三,我已经进行了足够长时间的调试以定位此问题:hibernate在对象本身上调用toString,而不是使用特定的ManyToMany设置对其ID进行调用.

There's not a fault in the toString methodz. I'm sure of that. First we can the in the stack there isn't any intermediate between the recursive calls other that hibernate. toString calls hibernate that calls the same toString. 2nd the toString works well when hibernate logging is switched off. That's when i turn it on that the exception appears. 3rd i've debug long enough to locate this problem : hibernate calls the toString on the object itself instead of its id with that particular ManyToMany setting.

我最初的问题是关于该设置的:可以吗?

My original question is about that setting : is it allowed ?

推荐答案

您似乎有以下类似之处:

You seem to have something akin the following:

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时,我陷入无限循环:

Now, when I call either of bar.toString or foo.toString I get into an infinite loop:

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

您根本不能拥有这样的toString方法-您需要确定一方打印集合,而另一方不这样做.

You simply cannot have toString methods like this - you need to decide on one party printing the collection and the other party not doing so.

这篇关于Hibernate:StackOverflowException记录ManyToMany关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆