无法编写JSON:无法懒惰地初始化角色集合:com.managem.model.Region.pays,无法初始化代理 - 无会话

问题描述 投票:1回答:1

我正在尝试创建一个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 – Internal Server Error

输入例外报告

message
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]-&gt;com.managem.model.Region[&quot;pays&quot;])

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)

注意此服务器的日志文件中提供了此错误的完整根本原因跟踪。

Apache Tomcat/9.0.13

java json spring proxy lazy-loading
1个回答
0
投票

错误是因为来自控制器的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);
© www.soinside.com 2019 - 2024. All rights reserved.