问题
After activating debug logging on org.hibernate.loader
, i have a StackOverflowException when hibernate tries to log something like "loading collection [com.Bar#42]"
The stack that's repeated is this one :
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)
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.
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;
}
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).
Is it a bug or is it a forbidden to have a JoinTable like that?
Thanks
I'm using hibernate version 3.6.0.Final.
EDIT :
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 ?
回答1:
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 + '}';
}
}
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
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.
来源:https://stackoverflow.com/questions/25938331/hibernate-stackoverflowexception-logging-manytomany-association