【问题标题】:add a lazy child in hibernate在休眠中添加一个懒惰的孩子
【发布时间】:2020-03-16 18:58:23
【问题描述】:

想要添加一个子对象而不获取它但得到 LazyInitializationException。 我的孩子是拥抱列表,所以不想为了添加一个孩子对象而获取所有孩子。

@Entity
public class JobRunId{
    @OneToMany(mappedBy = "jobRun", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<JobStep> jobSteps = new ArrayList<>();

    public void addStep(JobStep jobStep) {
        if (jobStep != null) {
            jobStep.setJobRun(this); 
            this.jobSteps.add(jobStep);// here getting LazyInitializationException
        }
    }
}

service class

jobRun = repository.findById(id);
//Dont want to do hibernate.initialize here as want to avoid fetch all 
 child records
JobStep jobStep = new JobStep();
//some jobStep status
jobRun.addStep(jobStep);//adding one step here to jobRun.getting error

有没有办法只添加一个子记录而不获取所有子记录。

【问题讨论】:

    标签: java hibernate spring-data


    【解决方案1】:

    直接坚持你的jobStep(即使用em.persist(jobStep)JobStepRepository.save(jobStep)之类的东西...

    注意:jobStep 实例应该具有对已持久化的 JobRunId 的引用...

    【讨论】:

      【解决方案2】:

      有没有办法只添加一个子记录而不获取所有子记录。

      考虑到您要添加给定JobRunIdJobStep 实体,您可以使用JOIN FETCH 指令,如查询。 JOIN FETCH 指令指示 Hibernate 发出一个INNER JOIN,以便将 JobRunId 与其 JobStep 一起获取。 createQuery 看起来类似:

          SELECT js
          FROM JobStep js
          JOIN fetch js.jobRunId 
          WHERE js.id = :jobId"
      

      另一种方法是使用 DTO 投影,如果您不想修改实体,则使用 DTO 投影。基本上,它允许您获取更少的列。

      我不确定这种关系的确切细节以及您为什么要这样管理。这是阅读Best way to handle LazyInitializationException的好文章。希望这会给您提供解决问题的见解。

      【讨论】:

      • 感谢您的回复。但是 join fetch 还将获取我实际上不想要的所有子对象,因为我的孩子有超过 1000 条记录并且只是添加一条记录,不想获取所有记录。请告诉我 dto 投影是如何工作的
      • @Rohit 鉴于您有one-to-many 关系,但您也有where 子句形式的过滤器。我用一篇文章更新了答案。
      猜你喜欢
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多