java - 无法写入 JSON:无法延迟初始化角色集合:com.managem.model.Region.pays,无法初始化代理 - 无会话
问题描述
我正在尝试创建一个 API 以从数据库中获取区域列表,每个区域都有一个国家列表。当我用户渴望获取但仅当国家列表为空时它才有效。当我使用延迟获取时,出现此错误:
WARNING: Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.managem.model.Region.pays, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.managem.model.Region.pays, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.managem.model.Region["pays"])]
这是模型:
@Entity
public class Region {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id_Region;
private String region;
private String description;
@OneToMany(mappedBy="region",
cascade= {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
private List<Pays> pays;
public List<Pays> getPays() {
return pays;
}
public void setPays(List<Pays> pays) {
this.pays = pays;
}
public int getIdRegion() {
return id_Region;
}
public void setIdRegion(int idRegion) {
this.id_Region = idRegion;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void add(Pays tempPays) {
if (pays==null) {
pays=new ArrayList<Pays>();
}
pays.add(tempPays);
tempPays.setRegion(this);
}
@Override
public String toString() {
return "Region [idRegion=" + id_Region + ", region=" + region + ", description=" + description + ", pays=" + pays
+ "]";
}
DAO 实现:
@Repository
public class RegionDAOImpl implements RegionDAO {
@Autowired
private SessionFactory sessionFactory;
@Override
public List<Region> listRegion() {
//retrieve the current Session and put it the session created
Session session = sessionFactory.getCurrentSession();
//create a query to get all the instances
Query<Region> query = session.createQuery("from Region", Region.class);
//return the list of results
return query.getResultList();
}
@Override
public Region getRegion(long id) {
//create a horairePostes instance and fill it with the object retrieved from the database
Region region = sessionFactory.getCurrentSession().get(Region.class, id);
//return the instance
return region;
}
@Override
public long save(Region region) {
//get the current session and save the object passed in the arguments
sessionFactory.getCurrentSession().save(region);
//return the object's id
return region.getIdRegion();
}
@Override
public void deleteRegion(long id) {
//retrieve the current session
Session session = sessionFactory.getCurrentSession();
//create a Region instance
//load the object corresponding to the id in the arguments in it
Region region = session.byId(Region.class).load(id);
//delete the object
session.delete(region);
}
@Override
public void updateRegion(long id, Region region) {
//retrieve the current session
Session session = sessionFactory.getCurrentSession();
//create a Region instance
//load the object corresponding to the id in the arguments in it
Region old_region = session.byId(Region.class).load(id);
//update old_region with the values in the region
old_region.setRegion(region.getRegion());
old_region.setDescription(region.getRegion());
//execute the changes (this changes are not committed yet)
session.flush();
}
服务实施:
@Service
public class RegionServiceImpl implements RegionService {
@Autowired
private RegionDAO regionDao;
@Override
@Transactional
public List<Region> listRegion() {
return regionDao.listRegion();
}
@Override
@Transactional
public Region getRegion(long id) {
return regionDao.getRegion(id);
}
@Override
@Transactional
public long save(Region region) {
return regionDao.save(region);
}
@Override
@Transactional
public void deleteRegion(long id) {
regionDao.deleteRegion(id);
}
@Override
@Transactional
public void updateRegion(long id, Region region) {
regionDao.updateRegion(id, region);
}
控制器:
@RestController
public class RegionController {
@Autowired
private RegionService regionService;
//Get all the regions
@GetMapping("/api/region")
public ResponseEntity<List<Region>> list(){
List<Region> list = regionService.listRegion();
return ResponseEntity.ok().body(list);
}
pom.xml
:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.managem</groupId>
<artifactId>gestionMines</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator-cdi -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-cdi</artifactId>
<version>5.4.2.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.2.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
</plugins>
</build>
</project>
这是我得到的错误:
État HTTP 500 – 内部服务器错误
类型报告 d'exception
信息Could not write JSON: failed to lazily initialize a collection of role: com.managem.model.Region.pays, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.managem.model.Region.pays, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.managem.model.Region["pays"])
描述Le serveur a rencontré une erreur interne qui l'a empêché de Satisfaire la requête。
例外
org.springframework.http.converter.HttpMessageNotWritableException:无法写入 JSON:无法延迟初始化角色集合:com.managem.model.Region.pays,无法初始化代理 - 无会话;嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:未能延迟初始化角色集合:com.managem.model.Region.pays,无法初始化代理 - 无 Session(通过引用链:java.util.ArrayList[ 0]->com.managem.model.Region["pays"]) org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:296) org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:103) org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:289) org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:223) org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) javax.servlet.http.HttpServlet.service(HttpServlet.java:634) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) javax.servlet.http.HttpServlet.service(HttpServlet.java:741) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
起因
com.fasterxml.jackson.databind.JsonMappingException:未能延迟初始化角色集合:com.managem.model.Region.pays,无法初始化代理 - 没有会话(通过引用链:java.util.ArrayList [0] - >com.managem.model.Region["pays"]) com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394) com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:353) com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316) com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:727) com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:400) com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1392) com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913) org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:287) org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:103) org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:289) org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:223) org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) javax.servlet.http.HttpServlet.service(HttpServlet.java:634) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) javax.servlet.http.HttpServlet.service(HttpServlet.java:741) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
起因
org.hibernate.LazyInitializationException:无法延迟初始化角色集合:com.managem.model.Region.pays,无法初始化代理 - 无会话 org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:582) org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:201) org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145) org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261) com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:97) com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:400) com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1392) com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913) org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:287) org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:103) org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:289) org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:223) org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) javax.servlet.http.HttpServlet.service(HttpServlet.java:634) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) javax.servlet.http.HttpServlet.service(HttpServlet.java:741) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
note La trace complète de la cause mère de cette erreur est disponible dans les fichiers journaux de ce serverur。
Apache Tomcat/9.0.13
解决方案
该错误是因为ResponseEntity.ok().body(list)
从您的控制器调用该方法Region.getPays()
以获取列表中每个区域的付款,同时尝试构造 JSON 来填充响应。问题是,由于pays
集合是 LAZY(默认情况下),Hibernate 尝试从数据库中获取这个集合。但是您的实体是分离的(您不在事务的范围内),因此出现了错误。
解决方案
您需要急切地获取其中pays
一个:
@OneToMany(mappedBy="region",
cascade= {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH}, fetch = FetchType.EAGER)
private List<Pays> pays;
或从 DAO 类修改查询以进行获取:
Query<Region> query = session.createQuery("from Region r JOIN FETCH r.pays", Region.class);
推荐阅读
- javascript - 在javascript上的数组值空间后获取字符
- python - MySQL 和 Python (pyodbc):找不到过程入口点 OPENSSL_sk_new_reserve
- azure - 为什么 Azure 子网未显示在所有资源中?
- opencv - 无法在 Heroku 上部署 Streamlit 应用程序 - 缺少 libgcc_s.so.1
- visual-studio-code - VSCODE:从launch.json访问cmake.buildDirectory
- python - 额外训练 NLP
- node.js - 非英文字符的节点 ODBC 问题
- java - 如何将搜索条件声明为参数 REST API 方法
- node.js - 尝试创建 React 角色系统时出现问题
- javascript - 检索值并将其放入对象中