Hello,
This is my first issue so pardon me if do something wrong and don't hesitate to tell me so i correct it.
I encounter a problem when i activate logging on a ManyToMany association. The ManyToMany is mapped with a join table that does not use the id but another attribute.
It worked well until i activated hibernate debug logging which causes a StackOverflowError :
java.lang.StackOverflowError
at java.lang.Object.hashCode(Native Method)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768)
at org.hibernate.tuple.EntityModeToTuplizerMapping.getTuplizerOrNull(EntityModeToTuplizerMapping.java:87)
at org.hibernate.tuple.entity.EntityMetamodel.getTuplizerOrNull(EntityMetamodel.java:404)
at org.hibernate.persister.entity.AbstractEntityPersister.getMappedClass(AbstractEntityPersister.java:3830)
at org.hibernate.type.CollectionType.getIdOfOwnerOrNull(CollectionType.java:403)
at org.hibernate.engine.StatefulPersistenceContext.getLoadedCollectionOwnerIdOrNull(StatefulPersistenceContext.java:781)
at org.hibernate.engine.StatefulPersistenceContext.getLoadedCollectionOwnerOrNull(StatefulPersistenceContext.java:752)
at org.hibernate.event.AbstractCollectionEvent.getLoadedOwnerOrNull(AbstractCollectionEvent.java:76)
at org.hibernate.event.InitializeCollectionEvent.<init>(InitializeCollectionEvent.java:38)
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:2826)
at java.lang.StringBuilder.append(StringBuilder.java:115)
at model.A.toString(A.java:25)
at org.hibernate.type.descriptor.java.AbstractTypeDescriptor.extractLoggableRepresentation(AbstractTypeDescriptor.java:109)
at org.hibernate.type.AbstractStandardBasicType.toLoggableString(AbstractStandardBasicType.java:292)
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:2826)
at java.lang.StringBuilder.append(StringBuilder.java:115)
at model.A.toString(A.java:25)
What happens is that i call a toString on my object, which loads its collection. Hibernate tries to log this loading. Normally it logs the id of the object but because my join table is not composed of the id, it tries to log the complete object, calling toString, hence the infinite loop.
Here is the class i use. B is just a class with an id and nothing else (no toString). I know i should add a notnull and a unique constraint on the string attribute to make the join table logic.
@Entity
public class A implements Serializable {
@Id
@GeneratedValue
public long id;
public String string;
@ManyToMany
@JoinTable(joinColumns = {
@JoinColumn(name="string", referencedColumnName = "string")
})
public List<B> bs;
@Override
public String toString() {
return "A{" +
"bs=" + bs +
'}';
}
}
I've joined a maven project with a junit test case showing the problem. Changing the log level in simplelogger.properties makes it work.
It affects versions prior to 4.x. I've seen it on 3.6.0 and 3.6.10. It works on 4.x but i cant upgrade at the moment.
Is it a bug? Is it forbidden to use such a join table? Is there a way to avoid it other than desactivating hibernate logging?
Thanks
|