我尝试使用多对多的集合映射,我有两个表: TASK和TASKRELATED,每个任务都可以有许多相关任务,每个相关任务都可以在许多父任务中完成。这是我的sql图:
这是我的实体:
@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);
}
这是我的ropository:
public interface ITaskRepository extends JpaRepository<Task, Long>,
QueryDslPredicateExecutor<Task>{
}
这是我的代码:
Task t = repository.findOne(1L);
这是我在mysql中的数据:
任务表
任务相关表
当我读取任务对象时,出现错误:
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)
请帮忙!
如果@ManyToMany(fetch=FetchType.EAGER)
,则会出现如下错误:
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)
答案 0 :(得分:1)
它无法初始化集合,您是否尝试在不初始化的情况下添加集合?:
@ManyToMany
@JoinTable(name = "taskRelated", joinColumns = { @JoinColumn(name = "relatedTaskId") }, inverseJoinColumns = { @JoinColumn(name = "taskId") })
private Set<Task> relatedTasks;
答案 1 :(得分:1)
正如异常所说,你试图在关闭会话后访问集合元素 - relatedTasks
,并且Hibernate默认会懒洋洋地加载集合元素。
因此您需要访问会话中的元素,或者您可以将获取类型添加到EAGER
@ManyToMany(fetch = FetchType.EAGER)
<强>更新强>
根据异常的stacktrace - LazyInitializationException: illegal access to loading collection
它有:
at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:434)
at org.nli.seoweb.domain.Task.hashCode(Task.java:36)
基于此,我假设您已覆盖hashCode
实体中的Task
方法,此方法正尝试访问Set
。由于Hibernate在这种情况下为Set
提供了PersistentSet
的包装类,因此在内部调用hashCode()
进行验证,检查Set
是否已完全初始化,然后抛出异常。
因此,请尝试修改您的Task.hashCode()
方法,并确保您没有使用Set
,并查看它是否解决了问题。
您也可以参考this post获取类似的例外情况。