休眠,JPA - 例子manytomany与两个表

问题描述:

我尝试使用多对多的集合映射,我有两个表: TASK和TASKRELATED,每个任务可以有许多相关的任务,每个相关的任务可以在许多父任务。这里是我的SQL图:休眠,JPA - 例子manytomany与两个表

enter image description here

这里是我的实体:

@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: 任务表
enter image description here
taskrelated表
enter image description here

当我做阅读任务对象的,有恩的错误:

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) 
+1

您忘记发布UsersServiceTest.testTask()。你知道,发生异常的地方。我可以猜测,没有任何JPA事务实际上是在代码周围的任何地方开始的。 – Gimby 2014-09-11 12:46:19

它不能初始化集合,你试图将设定的没有初始化它?:

@ManyToMany 
@JoinTable(name = "taskRelated", joinColumns = { @JoinColumn(name = "relatedTaskId") }, inverseJoinColumns = { @JoinColumn(name = "taskId") }) 
private Set<Task> relatedTasks; 
+0

我删除初始化,但同样的错误... – prilia 2014-09-11 12:27:06

由于异常说你正在尝试访问关闭会话后的收集元素 - relatedTasks,Hibernate默认情况下会延迟加载收集元素。

所以,你需要在会​​话中访问的元素或者你也可以抓取类型添加到EAGER

@ManyToMany(fetch = FetchType.EAGER) 

更新:

按堆栈跟踪异常 - 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类似的例外。

+0

也错误,我加了输出到问题 – prilia 2014-09-11 13:56:06

+0

好吧,正如Gimby所提到的添加引起此问题的代码。 – Chaitanya 2014-09-11 16:58:50

+0

添加知识库和代码阅读任务对象问题 – prilia 2014-09-11 17:21:37