我是新来的,最近开始学习春天和冬眠。我正在尝试开发RESTful服务来跟踪具有类别的项目。我有多对多关联(一个项目可以有多个类别,一个类别可以有多个项目),三个表:项目、类别和联接表项目类别。
我使用的是MySQL服务器、Spring Boot 1.3.1和Hibernate 4.3
我现在要做的是获取包含类别的项目列表和包含项目列表的类别。为此,我用API编写了整个应用程序,最后出现了LazyInitializationException。我试了很多方法,但都没用。(我可以设置fetch type EAGER,但这不是一个解决方案)。
例如,这是用于列出所有项的API:GET /api/item
这是输出:(不需要!):
原因:org.hibernate.LazyInitializationException:未能惰性地>初始化角色的集合:com.sk.itemlist.domain.Item.categories,无法初始化代理-没有会话
在org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
在org.hibernate.collection.internal.AbstractPersistentCollection.withtemporarysessionifneed(AbstractPersistentCollection.java:214)~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
在org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
在org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:160)~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
在com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializer(CollectionSerializer.java:101)~[jackson-databind-2.6.5.jar:2.6.5]
在com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializer(CollectionSerializer.java:24)~[jackson-databind-2.6.5.jar:2.6.5]
在com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:693)~[jackson-databind-2.6.5.jar:2.6.5]
在com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)~[jackson-databind-2.6.5.jar:2.6.5]
如果尝试获取所有类别GET /api/category,或按idGET /api/category/1获取类别,则会出现相同的错误
我的问题是:
如何摆脱LazyInitializationException?如何配置hibernate以重新打开会话?还是应该在DAO层初始化集合?
我读到关于DTO模式的文章,我不完全理解它是什么,我应该在这里深入研究吗?
我在尝试将数据插入项时注意到了这个问题。它只插入到项目表中,联接表和类别为空。我手动将数据添加到数据库中进行测试
你觉得整个应用程序怎么样?我在这里可以改进什么或者应该避免什么(如果有的话)
最后,我在这里上传了完整的项目:https://gitlab.com/sksh/ItemList.git
在参考资料中,您可以找到包含一些随机数据的数据库转储。使用有效的数据库凭据更新application.properties。

最佳答案

结果是:
你让hibernate去拿些东西
Hibernate会带来它们,但不会带来项目类别的信息。
在DB会话工作完成后(在CollectionSerializer中)尝试访问这些类别时,会出现该异常
您需要让hibernate和项目一起带来类别,这样您就可以在会话结束后使用then(iterate、list或else)。
你应该在刀层使用类似的东西。。

// fetch a Criteria reference and use join fetching
 Criteria c = currentSession().createCriteria(Item.class);
 c.setFetchMode("categories", FetchMode.JOIN);
 c.add(Restrictions.eq("id", id));
 Item result = (Item)c.uniqueResult();
 return result;

还有其他方法,比如在Item中声明
@ManyToMany(fetch=FetchType.EAGER)
private Set<Category> categories = new HashSet<>();

但这可能会导致性能问题

关于mysql - Hibernate多对多延迟初始化异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35214403/

10-11 22:28
查看更多