我正在尝试创建一个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>
这是我得到的错误:
输入例外报告
messageCould 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"])
description服务器遇到内部错误,导致无法满足请求。
例外
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"]) 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: 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"]) 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: failed to lazily initialize a collection of role: com.managem.model.Region.pays, could not initialize proxy - no Session 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)
注意此服务器的日志文件中提供了此错误的完整根本原因跟踪。
错误是因为来自控制器的ResponseEntity.ok().body(list)
调用方法Region.getPays()
来获取列表中每个区域的Pays,同时尝试构造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);