gpt4 book ai didi

java - Spring 中的 LazyInitializationException 与 JPA 实体

转载 作者:行者123 更新时间:2023-12-02 01:13:41 25 4
gpt4 key购买 nike

我想在 JPA 实体上从 EAGER 获取切换到 LAZY 获取,但随后出现错误。我已经尝试了很多解决方案,并且一直在寻找有效的解决方案 - 找不到任何适用于 Google 的解决方案...而且我也不希望该实体加入 fetch。

错误:org.hibernate.LazyInitializationException:无法延迟初始化角色集合:package.User.wallets,无法初始化代理 - 无 session

网络 Controller 文件:

@Controller
public class AppController {

@GetMapping("app/")
public ModelAndView app() {

ModelAndView mv = new ModelAndView();
mv.setViewName("app/index");

User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

List<Wallet> wallets = user.getWallets(); // error on this line
mv.addObject("wallets", wallets);

return mv;
}
}

用户文件:

@Entity
public class User {

@Id
@GeneratedValue
@Type(type="uuid-char")
private UUID id;

@Column(nullable = false)
private String email;

@Column(nullable = false)
private String firstName;

@Column(nullable = false)
private String lastName;

@Column(nullable = false)
private String password;

// FetchType.EAGER solves the error, but I can't have EAGER due to performance issues.
@OneToMany(mappedBy="user", fetch = FetchType.LAZY)
@Fetch(value = FetchMode.SUBSELECT)
private List<Wallet> wallets;

// ** getters and setters **

}

@Repository
public interface UserRepo extends JpaRepository<User, UUID> {

Optional<User> findByEmail(String email);

}

钱包文件:

@Entity
public class Wallet {

@Id
@GeneratedValue
@Type(type="uuid-char")
private UUID id;

@ManyToOne
@JoinColumn(name="user_id", nullable=false)
private User user;

@OneToOne
@JoinColumn(name="currency_id", nullable=false)
private Currency currency;

@Column(nullable = false)
private double balance;

// ** getters and setters **

}

@Repository
public interface WalletRepo extends JpaRepository<Wallet, UUID> {

Optional<Wallet> findByUserAndCurrency(User user, Currency currency);

}

感谢您阅读所有这些,我非常感谢您的回复。

最佳答案

问题的根源:

默认情况下,hibernate 延迟加载集合(关系),这意味着每当您在代码中使用集合时,hibernate 都会从数据库中获取集合,现在的问题是您正在 Controller 中获取集合(其中 JPA session 已关闭) )。这是导致异常的代码行(您正在加载评论集合):

List<Wallet> wallets = user.getWallets();

解决方案

您的用户实体中有此

 @OneToMany(mappedBy="user", fetch = FetchType.LAZY)
@Fetch(value = FetchMode.SUBSELECT)
private List<Wallet> wallets;

用这个

@OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL)
private List<Wallet> wallets;

Collections are lazy-loaded by default

更新的解决方案

这种特殊情况可以通过在 User 中添加 toString() 来重新定义 Lombok toString() 来解决

保留您的fetchType.LAZY而不是fetchType.EAGER并且将 toString 方法添加到您的用户实体

@Override
public String toString() {
return "User [id=" + id + ", email=" + email+ ", firstName=" + firstName+ ", lastName=" + lastName + ", password=" + password+ "]";
}

并向您添加钱包实体:

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

尝试将 @Transactional 添加到您的 Controller

关于java - Spring 中的 LazyInitializationException 与 JPA 实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58991466/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com