Java Hibernate FETCH。使用Spring数据存储库时急切地获取重复项

Java Hibernate FETCH。使用Spring数据存储库时急切地获取重复项,java,hibernate,spring-boot,spring-data-jpa,one-to-many,Java,Hibernate,Spring Boot,Spring Data Jpa,One To Many,我在Spring Data repository+Hibernate中遇到了一个问题(在Spring2.1.4中) 注意:在Spring1.5.x中一切正常 问题在于@ManyToOne(fetch=FetchType.Lazy)我在1.5中得到了正确的记录,但在spring 2.0中出现了错误,但是@ManyToOne(fetch=FetchType.Eager)我在列表中得到了重复的记录 我正在使用Spring数据存储库epicRepository.findById(长id)(以前Sprin

我在Spring Data repository+Hibernate中遇到了一个问题(在Spring
2.1.4
中)

注意:
Spring1.5.x中一切正常

问题在于
@ManyToOne(fetch=FetchType.Lazy)
我在1.5中得到了正确的记录,但在spring 2.0中出现了错误,但是
@ManyToOne(fetch=FetchType.Eager)
我在
列表中得到了重复的记录

我正在使用Spring数据存储库
epicRepository.findById(长id)
(以前Spring拥有
epicRepository.find()
,但他们在Spring 2.x中删除了它)

我不想使用
@Fetch(FetchMode.SELECT)
解决方案,因为它必须执行多个SELECT查询,并且将变得非常无性能

问题:

  • 如果我使用
    fetch=FetchType.Lazy
    我得到一个错误
    无法
    初始化代理-无会话
    (仅在升级到后启动 spring 2.x并返回了正确的行数)[当我试图获取代码后面的
    列表时,这个错误似乎没有问题。count
    ,当我在出错行之前通过调试器检查时,没有重复]
  • 因此,基于so中的一些解决方案,我使用了
    FetchType.Eager
    (我理解这对性能的影响,但无论如何 需要为另一项工作执行此操作,所以我这样做是因为此列表较小,需要在更新期间保留一些业务逻辑)。但现在我得到了重复的记录
  • 即使我所做的是错误的,列表中的计数(指重复的)也不应该是错误的

    我有以下
    JPA
    实体/表格

  • Epic
    ->[
    id
    (pk)、
    name
    status\u id
    (fk))
  • Story
    ->[
    id
    (pk)、
    name
    status\u id
    (fk)、
    epic\u id
    (fk))
  • 任务
    ->[
    id
    (主键),
    名称
    解析类型
    (fk),
    故事
    (fk))
  • 如果有任何错误,请原谅我(因为我使用不同的用例手动重新创建代码)

    Epic.java

    @Data
    public class Epic {
    
      @Id
      private Long id;
      private String name;
      @OneToOne(fetch = FetchType.Eager, optional = false)
      @JoinColumn(name = id, referenceColumnName = 'id', nullable = false, insertable = true, updatable = true)
      private Status status;
       @OneToMany(fetch = FetchType.Eager, cascade = ALL, mappedBy = epic)
      private List<Story> stories;
    }
    
    @Data
    public class Story {
    
      @Id
      private Long id;
      private String name;
      @OneToOne(fetch = FetchType.Eager, optional = false)
      @JoinColumn(name = id, referenceColumnName = 'id', nullable = false, insertable = true, updatable = true)
      private Status status;
       @OneToMany(fetch = FetchType.Eager, cascade = ALL, mappedBy = epic)
      private List<Task> tasks;
    
      @ManyToOne(fetch = FetchType.Lazy)
      // This is the problem area
      // Error if FetchType.Eager 
      // But duplicates in FetchType.Lazy
      @JoinColumn(name = "id", nullable = false) 
      private Epic epic;
    }
    
    @Data
    public class Task {
      @Id
      private Long id;
      private String name;
      @ManyToOne(fetch = FetchType.Lazy)
      @JoinColumn(name = "id")
      private Story story;
      @OneToOne (fetch = FetchType.Eager, optional = true)
      @JoinColumn (name = "id", )
      private Resolution resolution;
    }
    

    此问题以前已回答过多次。您可以选择:

    • 您应该迁移到
      Set
      s的所有
      EAGER
      集合
    • 使用集合的getter上的
      stream.distinct.collect
      手动执行重复筛选

    • 这个问题说它在春天工作得很好。1.5西安怀疑在早春版本中不支持热切。或者沿着这条线的东西。这就是Hibernate是如何工作的。