mysql - Hibernate 多对多延迟初始化异常

标签 mysql hibernate spring-boot many-to-many lazy-initialization

我是 JEE 的新手,最近开始学习 Spring 和 Hibernate。我正在尝试开发 RESTful 服务来跟踪带有类别的项目。我有多对多关联(一个项目可以有多个类别,一个类别可以有多个项目),三个表:项目、类别和连接表 item_category。

我正在使用 MySQL 服务器、Spring Boot 1.3.1 和 Hibernate 4.3

我现在想做的是获取带有类别的项目列表和带有项目列表的类别。我为此使用 API 编写了整个应用程序,并以 LazyInitializationException 结束。我尝试了很多方法,但没有帮助。 (我可以设置获取类型 EAGER 但这不是解决方案)。

例如,这是列出所有项目的 API:GET/api/item

这是输出:(没想到!):

Caused by: org.hibernate.LazyInitializationException: failed to lazily >initialize a collection of role: com.sk.itemlist.domain.Item.categories, could not initialize proxy - no Session at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:160) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final] at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:101) ~[jackson-databind-2.6.5.jar:2.6.5] at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24) ~[jackson-databind-2.6.5.jar:2.6.5] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:693) ~[jackson-databind-2.6.5.jar:2.6.5] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675) ~[jackson-databind-2.6.5.jar:2.6.5]

如果您尝试获取所有类别 GET/api/category 或按 id GET/api/category/1 的类别,则会出现同样的错误

所以这是我的问题:

  1. 如何摆脱 LazyInitializationException?如何配置 hibernate 以重新打开 session ?还是应该在 DAO 层初始化集合?
  2. 我阅读了 DTO 模式,但我不完全理解它是什么,我应该在这里深入挖掘吗?
  3. 我在尝试将数据插入项目时注意到问题。它只插入到项目表中,连接表和类别是空的。我手动将数据添加到数据库中进行测试
  4. 您对整个应用感觉如何?我可以在这里改进什么或我应该避免什么(如果有的话)

最后,我在这里上传了完整的项目:https://gitlab.com/sksh/ItemList.git
在资源中,您可以找到带有一些随机数据的数据库转储。使用有效的数据库凭据更新 application.properties。

最佳答案

发生的事情是:

  • 你让 hibernate 获取一些项目
  • Hibernate 带来它们,但不带来项目类别的信息。
  • 当您在数据库 session 工作完成后尝试访问这些类别时(在 CollectionSerializer 中),您会得到该异常
  • 您需要请求 hibernate 连同项目一起带来类别,以便您能够在 session 结束后使用(迭代、列表或其他)。

你应该在 DAO 级别使用类似的东西..

// 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/

相关文章:

java - 带有身份的 Spring Data 和 JPA + Hibernate 问题的 DDD 实现

java - Spring 应用程序中的字段未初始化

java - spring boot配置中list的环境变量

mysql - 为什么这个 SQL 触发器不起作用?选择总和并更新

PHP删除用户收藏夹

java - 线程 "main"javax.persistence.PersistenceException : org. hibernate.InstantiationException 中出现异常:实体没有默认构造函数:

maven - 在war中将Spring Boot APP部署到外部tomcat

java - 私有(private) JVM 上的 Spring boot ware 部署,无法访问 Controller

PHP:将两行插入 mySQL 数据库将不起作用。这段代码有什么问题?

通过 OpenSSL 的 MySQL TLS 验证失败