java 无法写入JSON:从delete方法返回实体对象时,无法惰性初始化集合

34gzjxbg  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(114)

当我练习实现OneToMany双向关联时,我在实现User实体的删除操作时遇到了问题,我收到了这个警告-Could not write JSON: failed to lazily initialize a collection, could not initialize proxy - no Session
所以,我有两个实体如下:

用户实体
@Entity
@Table(name = "users")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class User {

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

    private String username ;
    private String password ;
    private String email ;
    private String firstname ;
    private String lastname ;

    @OneToMany(
            mappedBy = "user" ,
            cascade = CascadeType.ALL ,
            orphanRemoval = true
    )
    private List<Playlist> playlists = new ArrayList<>() ;

    // getters and setters
}
播放列表实体
@Entity
@Table(name = "playlist")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class Playlist {

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

    private String name;
    private String description;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private User user;

    // getters and setters

}
UserController类
@RestController
@RequestMapping("/api/users")
public class userController {

    @Autowired
    UserService userService ;

    // ... other controller mappings

    @PostMapping("")
    public User createUser(@RequestBody User reqUser){
        return userService.createUser(reqUser) ;
    }

    @DeleteMapping("/{userID}")
    public User removeUser (@PathVariable Long userID) {
        return userService.removeUser(userID) ;
    }
}
UserService类中的removeUser方法
@Service
public class UserService {

    @Autowired
    UserRepo userRepo ;

    public List<User> getAllUsers() {
        List <User> users = new ArrayList<>() ;
        userRepo.findAll().forEach(users::add);
        return users ;
    }

    public User createUser(User reqUser) {
        User newUser = new User() ;
        newUser.setUsername(reqUser.getUsername());
        newUser.setEmail(reqUser.getEmail());
        newUser.setPassword(reqUser.getPassword());
        newUser.setFirstname(reqUser.getFirstname());
        newUser.setLastname(reqUser.getLastname());

        // adding playlists
        reqUser.getPlaylists().forEach( playlist -> {
            newUser.addPlaylist(playlist);
        });

        userRepo.save(newUser) ;

        return newUser ;
    }
    
    public User removeUser(Long userID) {

        // check if user exists
        User user = userRepo.findById(userID).orElseThrow(
                () -> new EntityNotFoundException("User doesn't exists with userID " + userID)
        );

        userRepo.deleteById(userID) ;
        return user ;
    }
}

用户的Get请求获取以下响应:

{
    "id": 20,
    "username": "poodie",
    "password": "randomPasswrod",
    "email": null,
    "firstname": "Raj",
    "lastname": "Bhushan",
    "playlists": [
        {
            "id": 27,
            "name": "playlist-01",
            "description": "first playlist",
            "user": 20,
            "songs": []
        },
        {
            "id": 28,
            "name": "playlist-02",
            "description": "first playlist",
            "user": 20,
            "songs": []
        }
    ]
}

可悲的是,当我想删除这个相同的用户,**即使它被删除,但我得到这个错误的 Postman **

{
    "timestamp": "2023-04-02T14:39:45.433+00:00",
    "status": 500,
    "error": "Internal Server Error",
    "path": "/api/users/20"
}

下面你可以看到堆栈跟踪中收到的警告:

2023-04-02 20:09:45.418  WARN 26500 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter
.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection, could not initialize proxy - no Session; nested exception is com.fasterxml
.jackson.databind.JsonMappingException: failed to lazily initialize a collection, could not initialize proxy - no Session (through reference chain: com.rudra.musicStreaming
.models.User["playlists"]->org.hibernate.collection.internal.PersistentBag[0]->com.rudra.musicStreaming.models.Playlist["songs"])]

该用户虽然从数据库中删除,但在堆栈跟踪中留下了这个警告,如何解决这个问题(Could not write JSON: failed to lazily initialize a collection, could not initialize proxy - no Session),这个问题的原因是什么?

注意:当我修改delete方法不返回任何User对象时,一切正常,但当我在执行删除操作时尝试返回User实体的对象时(如上面共享的代码所示),此警告在堆栈跟踪中出现。

svmlkihl

svmlkihl1#

LazyInitializationException
指示试图在打开的有状态会话的上下文之外访问未提取的数据。例如,在会话关闭后访问未初始化的代理或集合时,会发生此异常。
即将到来,因为您使用了存储库返回的代理对象。当您访问该对象时,代理试图初始化与该对象关联的集合。但它无法初始化集合,因为该对象已被删除,因此已不在会话中。

相关问题