Не удалось записать JSON: не удалось лениво инициализировать коллекцию ролей: com.managem.model.Region.pays, не удалось инициализировать прокси - нет сеанса - PullRequest
1 голос
/ 21 марта 2019

Я пытаюсь создать 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 - Внутренняя ошибка сервера

Тип Rapport d'exception

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;])

описание Служба, в которой вы можете найти ответы на все вопросы.

исключение

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)

причина MERE

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)

причина MERE

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)

примечание Слежение за работой de cette erreur est disonible dans les fichiers journaux de ce serveur.

Apache Tomcat / 9.0.13

1 Ответ

0 голосов
/ 21 марта 2019

Ошибка в том, что 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);
...