虽然fetch类型是懒惰的,但出于某种原因,hibernate会发送第二个请求并获取懒惰的请求。我已经处理这个问题几天了,出于某种原因,我不明白。我在互联网上尝试了一些方法,但不幸的是,我无法修复它,如果你能帮助我看看我的代码,我会非常感激。
用户实体
@Entity
@Table(name = "users")
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@Column(name = "username", length = 50)
private String username;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "user_friends" , joinColumns = @JoinColumn(name = "user_id") , inverseJoinColumns = @JoinColumn(name = "friend_id"))
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<User> friends = new HashSet<>();
}
字符串
用户服务
@Service
@Transactional
public class UserService implements ICrudService<User> {
@Autowired
private UserRepository repository;
@Override
@Transactional
public List<User> findAll() {
return repository.findAll();
}
@Override
@Transactional
public User findById(Long id) throws Exception {
return repository.findById(id).orElseThrow(() -> new Exception("Kullanici Bulunamadi"));
}
@Override
@Transactional
public User create(User user) {
return repository.save(user);
}
@Override
public void delete(Long id) {
repository.deleteById(id);
}
}
型
用户控制器
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/all")
public List<User> getUsers(){
return userService.findAll();
}
@GetMapping("/{userId}")
public User getUserById(@PathVariable Long userId) throws Exception {
return userService.findById(userId);
}
@PostMapping
public User saveUser(@RequestBody User user){
return userService.create(user);
}
@DeleteMapping("/{userId}")
public void deleteUserById(@PathVariable Long userId){
userService.delete(userId);
}
}
型
我使用JpaReository作为服务中的存储库
“/users/all”的输出如下所示
输出
[
{
"id": 1,
"username": "testUser",
"email": "[email protected]",
"password": "verystrongpasword",
"friends": []
}
]
型
这是休眠sql格式
Hibernate:
select
u1_0.id,
u1_0.email,
u1_0.password,
u1_0.username
from
users u1_0
Hibernate:
select
f1_0.user_id,
f1_1.id,
f1_1.email,
f1_1.password,
f1_1.username
from
user_friends f1_0
join
users f1_1
on f1_1.id=f1_0.friend_id
where
f1_0.user_id=?
型
2条答案
按热度按时间cnh2zyt31#
当属性的fetch type为
Lazy
时,当属性的getter被调用时,数据将按需检索。当响应被发送时,User
被序列化为json,json库通常使用getters -getFriends()
被底层库反射调用。解决方案(以及良好的实践)是使用
DTO
作为响应/请求,而不是实体。wqnecbli2#
这个问题是由
Lombok
@Data
注解触发的,因为在后台它使用@ToString
,默认情况下使用class
的所有字段来创建它。有两种可能的解决方案:
1.创建你自己的
toString()
方法,然后Lombok
会回退生成一个toString。2.添加
@ToString
注解,并使用@ToString.Exclude
排除所有惰性和双向字段。在您的情况下,类似于下一个:字符串
关于Lombok-Data-Ojects-Arent-Entities和其他案例的更深入的细节,你可以找到Marten代努姆的一篇好文章。