Reputation: 1016
I try to use with many to many collection mapping, I hae two tables : TASK and TASKRELATED, every task can has many related tasks and every related task can be in many parent tasks. here is my sql diagram:
Here is my entity :
@Entity
public class Task {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long taskId;
@ManyToMany
@JoinTable(name = "taskRelated", joinColumns = { @JoinColumn(name = "relatedTaskId") }, inverseJoinColumns = { @JoinColumn(name = "taskId") })
private Set<Task> relatedTasks = new HashSet<Task>(0);
}
Here is my ropository :
public interface ITaskRepository extends JpaRepository<Task, Long>,
QueryDslPredicateExecutor<Task>{
}
This is my code :
Task t = repository.findOne(1L);
This is my data in mysql:
task table
taskrelated table
When I do read of task object, there is en error:
failed to lazily initialize a collection of role: org.Task.relatedTasks, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.Task.relatedTasks, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:122)
at org.hibernate.collection.PersistentSet.size(PersistentSet.java:162)
at com.github.springtestdbunit.sample.service.UsersServiceTest.testTask(UsersServiceTest.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
Please help !
in case of @ManyToMany(fetch=FetchType.EAGER)
there is error like this :
illegal access to loading collection
org.hibernate.LazyInitializationException: illegal access to loading collection
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:366)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:434)
at org.Task.hashCode(Task.java:36)
at java.util.HashMap.hash(HashMap.java:351)
at java.util.HashMap.put(HashMap.java:471)
at java.util.HashSet.add(HashSet.java:217)
at java.util.AbstractCollection.addAll(AbstractCollection.java:334)
at org.hibernate.collection.PersistentSet.endRead(PersistentSet.java:352)
at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:261)
at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:246)
at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:219)
at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:1005)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:993)
Upvotes: 1
Views: 901
Reputation: 21445
As the exception says you are trying to access the collection elements - relatedTasks
after closing the session and Hibernate lazily loads the collection elements by default.
So you need to access the elements within the session or alternatively you can add the fetch type to EAGER
@ManyToMany(fetch = FetchType.EAGER)
Update:
As per stacktrace for exception - LazyInitializationException: illegal access to loading collection
it has:
at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:434)
at org.nli.seoweb.domain.Task.hashCode(Task.java:36)
Based on this I am assuming you have overridden the hashCode
method in Task
entity and this method is trying to access the Set
. As Hibernate provides a wrapper class for the Set
which is PersistentSet
in this case, calling hashCode()
internally has a validation that checks if the Set
is fully initialized or not and then throw the exception.
So try modifying your Task.hashCode()
method and make sure you are not using the Set
in it, and see if it fixes the issue.
You can also refer to this post for similar exception.
Upvotes: 1
Reputation: 70
It cannot initialize the collection, have you tried adding the set without initializing it?:
@ManyToMany
@JoinTable(name = "taskRelated", joinColumns = { @JoinColumn(name = "relatedTaskId") }, inverseJoinColumns = { @JoinColumn(name = "taskId") })
private Set<Task> relatedTasks;
Upvotes: 1