java - HttpMessageNotWritableException : Could not write JSON: Could not initialize proxy AFTER adding data into DB

标签 java hibernate spring-boot

这是我的问题。从 POSTMAN 发送 POST 请求以在 SQL 数据库中创建/添加一行后,我无法编写 JSON。我需要服务器发回添加条目的响应,以便检索 SQL 生成的 ID。

当新的 Case 条目是两个实体(UserApplication)的子项以及一个实体的孙子项时,我会遇到此问题(所有者)。

*User(Owner)
|\
| *Application
|/ 
*Case

我是新手,目前正在使用 Spring Boot JPA 包。

我知道很多人提出了与上述错误相关的问题。据我所知,没有任何关于我的案件的信息。所有这些都涉及通过 HTTP GET 方法进行的修复。如果您找到了一些,请引导我找到它们。或者请帮忙解答我的疑问。如有任何帮助,我们将不胜感激!

我在这里附上我的代码:

用户实体

    package com.lightlce.CRUD.Entities;
    import javax.persistence.*;
    @Entity(name = "User")
    @Table(name = "User", schema = "dbo")
    public class User {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;

    private String staffId;

    private String username;

    private String role;

    public User (){}

    public User(Integer id, String staffId, String username, String role) {
        this.id = id;
        this.staffId = staffId;
        this.username = username;
        this.role = role;
    }

    // Getters and Setters
    }

应用程序实体

    package com.lightlce.CRUD.Entities;
    import javax.persistence.*;
    @Entity(name = "Application")
    @Table(name = "InvApplication", schema = "dbo")
    public class Application {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String applicationName;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ownerId")
    private User owner;

    public Application(){}

    public Application(Integer id, String applicationName, User owner) {
        this.id = id;
        this.applicationName = applicationName;
        this.owner = owner;
    }

    // Getters and Setters
    }

案例实体

package com.lightlce.CRUD.Entities;

import com.lightlce.CRUD.AuditModel.Auditable;

import javax.persistence.*;

@Entity(name = "Case")
@Table(name = "InvCase", schema = "dbo")
public class Case extends Auditable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "userId")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "applicationId")
    private Application application;

    //redacted

    public Case() {
    }

    public Case(Integer id, User user, Application application) {
        this.id = id;
        this.user = user;
        this.application = application;
    }

    // Getters and Setters
}

案例 Controller

package com.lightlce.CRUD.Controllers;

import com.lightlce.CRUD.Entities.Application;
import com.lightlce.CRUD.Entities.Case;
import com.lightlce.CRUD.Entities.User;
import com.lightlce.CRUD.Repository.ApplicationRepository;
import com.lightlce.CRUD.Repository.CaseRepository;
import com.lightlce.CRUD.Repository.UserRepository;
import com.lightlce.CRUD.Services.ApplicationService;
import com.lightlce.CRUD.Services.CaseService;
import com.lightlce.CRUD.Services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

@RestController
public class CaseController {

    @Autowired
    private CaseService caseService;

    @Autowired
    private UserService userService;

    @Autowired
    private ApplicationRepository applicationRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private CaseRepository caseRepository;

    @Autowired
    private UserController userController;

    @RequestMapping("cases")
    public Page<Case> getAllCases(Pageable pageable) {
        return caseService.getAllCases(pageable);
    }

    @PostMapping("cases/add")
    public Case addCase(@RequestBody Case aCase) {
        User staff = userService.searchUser(aCase.getUser()); //Finds the user based on ID provided
        Application application = applicationRepository.findById(aCase.getApplication().getId()).get(); //Finds the application based on ID provided
        aCase.setUser(staff);
        aCase.setApplication(application);
        return caseService.addCase(aCase);
    }
}

案例服务

package com.lightlce.CRUD.Services;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.lightlce.CRUD.Entities.Application;
import com.lightlce.CRUD.Entities.Case;
import com.lightlce.CRUD.Entities.User;
import com.lightlce.CRUD.Repository.CaseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Service
public class CaseService {

    @Autowired
    private CaseRepository caseRepository;

    @Autowired
    private UserService userService;

    public Page<Case> getAllCases(Pageable pageable){
        return caseRepository.customFindAll(pageable);
    }

    public Case addCase(Case aCase) {
        caseRepository.save(aCase);
        return aCase;
    }
}

案例库

package com.lightlce.CRUD.Repository;

import com.lightlce.CRUD.Entities.Case;
import com.lightlce.CRUD.Entities.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

@Repository
public interface CaseRepository extends JpaRepository<Case, Integer>{
    Page<Case> findAll(Pageable pageable);

    @Query(value = "SELECT c FROM com.lightlce.CRUD.Entities.Case c " +
            "JOIN FETCH c.user u " +
            "JOIN FETCH c.application a " +
            "JOIN FETCH a.owner o",
            countQuery = "SELECT COUNT(c) FROM  com.lightlce.CRUD.Entities.Case c " +
                    "JOIN c.user u " +
                    "JOIN c.application a " +
                    "JOIN a.owner o")
    Page<Case> customFindAll(Pageable pageable);
}

发布http://localhost:8080/cases/add

{
    "user": {
        "staffId": "TEST123"
    },
    "application":{
        "id": 2
    }
}

预期响应

{
      "created_at": "2020-05-13T09:34:04.093+0000",
      "modified_at": "2020-05-13T09:34:04.093+0000",
      "id": 1
      "user": {
             "id": 1,
             "staffId": "TEST123",
             "username": "lightlce",
             "role": "admin"
      },
      "application": {
             "id": 2,
             "applicationName": "ApplicationDemo",
             "owner": {
                 "id": 1,
                 "staffId": "TEST123",
                 "username": "lightlce",
                 "role": "admin"
             }
      }
}

postman 异常

{
    "timestamp": "2020-05-14T02:36:40.999+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "Could not write JSON: could not initialize proxy [com.lightlce.CRUD.Entities.User#2] - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy [com.lightlce.CRUD.Entities.User#2] - no Session (through reference chain: com.lightlce.CRUD.Entities.Case[\"application\"]->com.lightlce.CRUD.Entities.Application[\"owner\"]->com.lightlce.CRUD.Entities.User$HibernateProxy$QRpaILkJ[\"staffId\"])",
    "path": "/cases/add"
}

Springboot日志

2020-05-14 10:36:38.262 DEBUG 50878 --- [nio-8080-exec-6] org.hibernate.SQL                        : 
    select
        user0_.id as id1_0_,
        user0_.role as role2_0_,
        user0_.staffId as staffId3_0_,
        user0_.username as username4_0_ 
    from
        dbo.InvAllUser user0_ 
    where
        user0_.staffId=?
Hibernate: 
    select
        user0_.id as id1_0_,
        user0_.role as role2_0_,
        user0_.staffId as staffId3_0_,
        user0_.username as username4_0_ 
    from
        dbo.InvAllUser user0_ 
    where
        user0_.staffId=?
2020-05-14 10:36:38.278 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [TEST123]
2020-05-14 10:36:38.808 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([id1_0_] : [INTEGER]) - [1]
2020-05-14 10:36:38.811 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([role2_0_] : [VARCHAR]) - [admin]
2020-05-14 10:36:38.812 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([staffId3_0_] : [VARCHAR]) - [TEST123]
2020-05-14 10:36:38.812 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([username4_0_] : [VARCHAR]) - [lightlce]
2020-05-14 10:36:38.837 DEBUG 50878 --- [nio-8080-exec-6] org.hibernate.SQL                        : 
    select
        applicatio0_.id as id1_1_0_,
        applicatio0_.applicationName as applicat2_1_0_,
        applicatio0_.ownerId as ownerId3_1_0_ 
    from
        dbo.InvApplication applicatio0_ 
    where
        applicatio0_.id=?
Hibernate: 
    select
        applicatio0_.id as id1_1_0_,
        applicatio0_.applicationName as applicat2_1_0_,
        applicatio0_.ownerId as ownerId3_1_0_ 
    from
        dbo.InvApplication applicatio0_ 
    where
        applicatio0_.id=?
2020-05-14 10:36:38.839 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [INTEGER] - [2]
2020-05-14 10:36:39.427 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([applicat2_1_0_] : [VARCHAR]) - [ApplicationDemo]
2020-05-14 10:36:39.427 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([ownerId3_1_0_] : [INTEGER]) - [2]
2020-05-14 10:36:39.546 DEBUG 50878 --- [nio-8080-exec-6] org.hibernate.SQL                        : 
    insert 
    into
        dbo.InvCase
        (created_at, modified_at, applicationId, approverId, caseDesc, caseTitle, caseType, status, userId) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: 
    insert 
    into
        dbo.InvCase
        (created_at, modified_at, applicationId, approverId, caseDesc, caseTitle, caseType, status, userId) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?)
2020-05-14 10:36:39.553 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [TIMESTAMP] - [Thu May 14 10:36:39 SGT 2020]
2020-05-14 10:36:39.555 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [TIMESTAMP] - [Thu May 14 10:36:39 SGT 2020]
2020-05-14 10:36:39.555 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [INTEGER] - [2]
2020-05-14 10:36:39.555 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [INTEGER] - [1]
2020-05-14 10:36:39.555 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [VARCHAR] - [ApplicationDemo]
2020-05-14 10:36:39.555 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [6] as [VARCHAR] - [TEST123]
2020-05-14 10:36:39.555 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [7] as [VARCHAR] - [new]
2020-05-14 10:36:39.556 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [8] as [VARCHAR] - [Pending]
2020-05-14 10:36:39.557 TRACE 50878 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder      : binding parameter [9] as [INTEGER] - [1]
2020-05-14 10:36:40.987  WARN 50878 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: could not initialize proxy [com.lightlce.CRUD.Entities.User#2] - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy [com.lightlce.CRUD.Entities.User#2] - no Session (through reference chain: com.lightlce.CRUD.Entities.Case["application"]->com.lightlce.CRUD.Entities.Application["owner"]->com.lightlce.CRUD.Entities.User$HibernateProxy$QRpaILkJ["staffId"])]

最佳答案

您的代码存在很多问题,我真的不知道如何帮助解决它。 但作为快速修复尝试为用户对象创建一个新的实体类。

关于java - HttpMessageNotWritableException : Could not write JSON: Could not initialize proxy AFTER adding data into DB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61788369/

相关文章:

java - Intellij Idea 运行/调试配置和 Gradle 任务中的 SSH 隧道

java - 如何在 Java 8 (Spring Boot) 应用程序中设置最大非堆内存?

java - CORS政策: No 'Access-Control-Allow-Origin' header is present on the requested resource Spring Boot Rest API

java - 验证 PUT 操作的资源

java - 我可以使用 Mapstruct 在单个 Java 类中调用多个外部映射器吗?

java - Hibernate - 查询为实体中的所有字段返回空值,而同一查询从数据库中完美返回

java - JPA/Hibernate 查询构造

java - If 语句中的可执行语句

java - Runtime.getRuntime().exec error=13 权限被拒绝

java - 使用 hibernate 的外键连接