Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring中带有JPA实体的LazyInitializationException_Java_Spring - Fatal编程技术网

Java Spring中带有JPA实体的LazyInitializationException

Java Spring中带有JPA实体的LazyInitializationException,java,spring,Java,Spring,我想在我的JPA实体上从急切抓取切换到懒惰抓取,但随后我得到了一个错误。我已经尝试了很多解决方案,并且已经搜索了一段时间,寻找一个有效的解决方案-在谷歌上找不到任何有效的解决方案。。。我也不希望实体加入fetch 错误:org.hibernate.LazyInitializationException:未能延迟初始化角色集合:package.User.wallet,无法初始化代理-无会话 网络控制器文件: @Controller public class AppController {

我想在我的JPA实体上从急切抓取切换到懒惰抓取,但随后我得到了一个错误。我已经尝试了很多解决方案,并且已经搜索了一段时间,寻找一个有效的解决方案-在谷歌上找不到任何有效的解决方案。。。我也不希望实体加入fetch

错误:org.hibernate.LazyInitializationException:未能延迟初始化角色集合:package.User.wallet,无法初始化代理-无会话

网络控制器文件:

@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;
    }
}

@控制器
公共类AppController{
@GetMapping(“app/”)
公共模型和视图应用程序(){
ModelAndView mv=新ModelAndView();
mv.setViewName(“应用程序/索引”);
User User=(User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List wallets=user.getWallets();//此行出错
mv.addObject(“钱包”,钱包);
返回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);

}

@实体
公共类用户{
@身份证
@生成值
@类型(Type=“uuid char”)
私有UUID;
@列(nullable=false)
私人字符串电子邮件;
@列(nullable=false)
私有字符串名;
@列(nullable=false)
私有字符串lastName;
@列(nullable=false)
私有字符串密码;
//FetchType.EAGER解决了错误,但由于性能问题,我无法使用EAGER。
@OneToMany(mappedBy=“user”,fetch=FetchType.LAZY)
@Fetch(值=FetchMode.SUBSELECT)
私人清单钱包;
//**接球手和接球手**
}
@存储库
公共接口UserRepo扩展了JpaRepository{
可选findByEmail(字符串电子邮件);
}
钱包文件:

@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);

}
@实体
公务舱钱包{
@身份证
@生成值
@类型(Type=“uuid char”)
私有UUID;
@许多酮
@JoinColumn(name=“user\u id”,nullable=false)
私人用户;
@奥内托内
@JoinColumn(name=“currency\u id”,nullable=false)
私人货币;
@列(nullable=false)
私人双平衡;
//**接球手和接球手**
}
@存储库
公共接口WalletRepo扩展了JpaRepository{
可选findByUserAndCurrency(用户、货币);
}

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

您问题的根源:

默认情况下,hibernate延迟加载集合(关系),这意味着当您在代码中使用集合时,hibernate会从数据库中获取集合,现在的问题是您正在控制器中获取集合(JPA会话关闭的地方)。这是导致异常的代码行(正在加载注释集合的位置):

并添加到您的钱包实体中:

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

尝试将
@Transactional
添加到控制器中

问题的根源:

默认情况下,hibernate延迟加载集合(关系),这意味着当您在代码中使用集合时,hibernate会从数据库中获取集合,现在的问题是您正在控制器中获取集合(JPA会话关闭的地方)。这是导致异常的代码行(正在加载注释集合的位置):

并添加到您的钱包实体中:

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

尝试将
@Transactional
添加到您的控制器中

您必须在
AppController
类上方添加
org.springframework.transaction.annotation.Transactional
,然后延迟加载将起作用

例如:

import org.springframework.transaction.annotation.Transactional;
@控制器
@交易的
公共类AppController{
@GetMapping(“app/”)
公共模型和视图应用程序(){
ModelAndView mv=新ModelAndView();
mv.setViewName(“应用程序/索引”);
User User=(User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List wallets=user.getWallets();//此行出错
mv.addObject(“钱包”,钱包);
返回mv;
}
}
如果它不起作用,您可能没有启用事务管理(这通常由Spring Boot自动配置配置)。请尝试添加
@EnableTransactionManagement
,例如,在主应用程序类上方,使用
@SpringBootApplication
注释

你也可以试试下面这句话:

Hibernate.initialize(user.getWallets());

您必须在
AppController
类上方添加
org.springframework.transaction.annotation.Transactional
,然后延迟加载将起作用

例如:

import org.springframework.transaction.annotation.Transactional;
@控制器
@交易的
公共类AppController{
@GetMapping(“app/”)
公共模型和视图应用程序(){
ModelAndView mv=新ModelAndView();
mv.setViewName(“应用程序/索引”);
User User=(User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List wallets=user.getWallets();//此行出错
mv.addObject(“钱包”,钱包);
返回mv;
}
}
如果它不起作用,您可能没有启用事务管理(这通常由Spring Boot自动配置配置)。请尝试添加
@EnableTransactionManagement
,例如,在主应用程序类上方,使用
@SpringBootApplication
注释

你也可以试试下面这句话:

Hibernate.initialize(user.getWallets());

这是由于SecurityContextHolder.getContext().getAuthentication().getPrincipal()中的用户对象 已关闭连接,即使在控制器类中注释了@Transaction

我必须像这样更改控制器类:

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

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

        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        User user = userRepo.findByUsername(userDetails.getUsername()).orElse(null);

        List<Wallet> wallets = user.getWallets(); // no error anymore
        mv.addObject("wallets", wallets);

        return mv;
    }
@GetMapping(“app/”)
公共模型和视图应用程序(){
ModelAndView mv=新ModelAndView();
mv.setViewName(“应用程序/索引”);
用户详细信息用户详细信息
@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;
    @GetMapping("app/")
    public ModelAndView app() {

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

        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        User user = userRepo.findByUsername(userDetails.getUsername()).orElse(null);

        List<Wallet> wallets = user.getWallets(); // no error anymore
        mv.addObject("wallets", wallets);

        return mv;
    }