无法写入 JSON:延迟初始化角色集合失败:
Could not write JSON: failed to lazily initialize a collection of role:
我在获取类型时遇到错误,我不知道如何解决!如果可以,请帮助我。 :D。使用 java 8
命令行运行程序:
@Autowired CustomTableRepository tr;
@Autowired UserRepository ur;
@Autowired RoleRepository rr;
@Bean
CommandLineRunner commandLineRunner() {
return args -> {
tr.save(new CustomTable(null, true, null));
tr.save(new CustomTable(null, true, null));
tr.save(new CustomTable(null, true, null));
tr.save(new CustomTable(null, true, null));
tr.save(new CustomTable(null, true, null));
ur.save(new User(null, "cpthermes", "thanatos", 123987456l, 3123231l, null,null));
ur.save(new User(null, "moni1008", "milky", 123987456l, 31232131l, null, null));
ur.save(new User(null, "mario", "zoro123", 1231231l, 32123l, null, null));
};
}
模特类:
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Reservation {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private Boolean accepted;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@OneToOne
@JoinColumn(name = "table_id")
private CustomTable table;
private LocalTime time;
}
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String username;
private String password;
private Long number;
private Long balance;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Reservation> reservations;
@ManyToMany
private Collection<Role> roles;
}
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role {
@Id
@GeneratedValue
private Long id;
private String type;
}
错误:
Could not write JSON: failed to lazily initialize a collection of role: com.mile.pc.mile.restoraunt.app.model.User.reservations, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.mile.pc.mile.restoraunt.app.model.User.reservations, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.mile.pc.mile.restoraunt.app.model.User["reservations"])
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.mile.pc.mile.restoraunt.app.model.User.reservations, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.mile.pc.mile.restoraunt.app.model.User.reservations, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.mile.pc.mile.restoraunt.app.model.User["reservations"])
.......
...................................
...................................
...................................
...................................
...................................
喜欢读书。
问题是在 Spring 尝试将您的实体转换为 JSON 时,Hibernate 无法从数据库中检索延迟加载的 reservations
。您有几种可能性来解决这个问题:
- 使用FetchType.EAGER策略
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String username;
private String password;
private Long number;
private Long balance;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Reservation> reservations;
@ManyToMany
private Collection<Role> roles;
}
- 在您的自定义存储库方法中使用连接提取:
@Query(value = "SELECT u FROM User u JOIN FETCH u.reservations")
List<User> findAllUsers();
您可以在以下在线资源中阅读有关此问题的更多信息:https://www.baeldung.com/hibernate-initialize-proxy-exception
对于 @OneToMany
和 @ManyToMany
hibernate 默认使用惰性获取方法。即当您要求它获取父实体时,它根本不会加载您的子实体。所以你可以有两种更简单的方法来克服这个问题。
- 在
Reservations
上使用fetch=FetchType.EAGER
。
只需在下面更新角色class。
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Reservation> reservations;
但请注意性能问题。当您请求 Role
实体时,Hibernate 将始终加载 Reservation
实体。如果这不是您的应用程序关心的问题,您可以轻松地进行此操作。
- 使用
JOIN FETCH
方法
使用 join fetch
定义 @Query
方法并使用它而不是预定义的
find()
方法。通过这种方式,您可以询问 hibernate 要加载哪些其他表
每当您要求加载父实体时。
@Query(value = "SELECT u FROM User u JOIN FETCH u.reservations")
List<User> findUsersWithReservations();
下面的文章有关于它的更多详细信息以及一些其他方法。
我在获取类型时遇到错误,我不知道如何解决!如果可以,请帮助我。 :D。使用 java 8
命令行运行程序:
@Autowired CustomTableRepository tr;
@Autowired UserRepository ur;
@Autowired RoleRepository rr;
@Bean
CommandLineRunner commandLineRunner() {
return args -> {
tr.save(new CustomTable(null, true, null));
tr.save(new CustomTable(null, true, null));
tr.save(new CustomTable(null, true, null));
tr.save(new CustomTable(null, true, null));
tr.save(new CustomTable(null, true, null));
ur.save(new User(null, "cpthermes", "thanatos", 123987456l, 3123231l, null,null));
ur.save(new User(null, "moni1008", "milky", 123987456l, 31232131l, null, null));
ur.save(new User(null, "mario", "zoro123", 1231231l, 32123l, null, null));
};
}
模特类:
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Reservation {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private Boolean accepted;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@OneToOne
@JoinColumn(name = "table_id")
private CustomTable table;
private LocalTime time;
}
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String username;
private String password;
private Long number;
private Long balance;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Reservation> reservations;
@ManyToMany
private Collection<Role> roles;
}
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role {
@Id
@GeneratedValue
private Long id;
private String type;
}
错误:
Could not write JSON: failed to lazily initialize a collection of role: com.mile.pc.mile.restoraunt.app.model.User.reservations, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.mile.pc.mile.restoraunt.app.model.User.reservations, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.mile.pc.mile.restoraunt.app.model.User["reservations"])
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.mile.pc.mile.restoraunt.app.model.User.reservations, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.mile.pc.mile.restoraunt.app.model.User.reservations, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.mile.pc.mile.restoraunt.app.model.User["reservations"])
....... ................................... ................................... ................................... ................................... ................................... 喜欢读书。
问题是在 Spring 尝试将您的实体转换为 JSON 时,Hibernate 无法从数据库中检索延迟加载的 reservations
。您有几种可能性来解决这个问题:
- 使用FetchType.EAGER策略
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String username;
private String password;
private Long number;
private Long balance;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Reservation> reservations;
@ManyToMany
private Collection<Role> roles;
}
- 在您的自定义存储库方法中使用连接提取:
@Query(value = "SELECT u FROM User u JOIN FETCH u.reservations")
List<User> findAllUsers();
您可以在以下在线资源中阅读有关此问题的更多信息:https://www.baeldung.com/hibernate-initialize-proxy-exception
对于 @OneToMany
和 @ManyToMany
hibernate 默认使用惰性获取方法。即当您要求它获取父实体时,它根本不会加载您的子实体。所以你可以有两种更简单的方法来克服这个问题。
- 在
Reservations
上使用fetch=FetchType.EAGER
。
只需在下面更新角色class。
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Reservation> reservations;
但请注意性能问题。当您请求 Role
实体时,Hibernate 将始终加载 Reservation
实体。如果这不是您的应用程序关心的问题,您可以轻松地进行此操作。
- 使用
JOIN FETCH
方法
使用 join fetch
定义 @Query
方法并使用它而不是预定义的
find()
方法。通过这种方式,您可以询问 hibernate 要加载哪些其他表
每当您要求加载父实体时。
@Query(value = "SELECT u FROM User u JOIN FETCH u.reservations")
List<User> findUsersWithReservations();
下面的文章有关于它的更多详细信息以及一些其他方法。