【问题标题】:Spring Boot JPA - ManyToOne relationship causes extra sqlSpring Boot JPA - ManyToOne 关系导致额外的 sql
【发布时间】:2019-11-17 08:36:07
【问题描述】:

我有 3 个具有简单关系的对象,如下所示:

大学:

@Entity
public class University {

  @Id
  @GeneratedValue
  private Long id;

  private String name;

}

教师:

@Entity
public class Faculty {

  @Id
  @GeneratedValue
  private Long id;

  private String name;

  @Column(name = "university_id", nullable = false)
  private Long universityId;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinFetch(value = JoinFetchType.OUTER)
  @JoinColumn(name = "university_id", insertable = false, updatable = false, nullable = false)
  private University university;
}

专业:

@Entity
public class Specialty {

  @Id
  @GeneratedValue
  private Long id;

  private String name;

  @Column(name = "faculty_id", nullable = false)
  private Long facultyId;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinFetch(value = JoinFetchType.OUTER)
  @JoinColumn(name = "faculty_id", insertable = false, updatable = false, nullable = false)
  private Faculty faculty;
}

我正在使用 EclipseLink 和 Spring CrudRepository 来操作这些实体。 当我打电话时

specialtyRepository.findAll();

我得到了 sql

SELECT * FROM special LEFT OUTER JOIN Faculty ON (faculty.ID = special.faculty_id) ...

还有额外的 sql 之类的

SELECT * FROM university WHERE ((ID = ?)) ...

我想阻止这个sql请求;

谁能告诉我如何解决这个问题? 感谢您的任何提示

【问题讨论】:

  • 删除 fetch = FetchType.LAZY,或编写并执行使用 left join fetch 的 JPQL 查询,以便一次性加载该专业及其教师。
  • 我想在没有自定义查询的情况下解决它; Remove fetch = FetchType.LAZY - 没有帮助;是否可以忽略学院中的大学关系?我只需要简单的专业信息和没有嵌套关系的教师信息(教师对象中的大学必须等于 null)
  • spring jpa中如果执行join,那些额外的sql语句是不可避免的。
  • 为什么要使用 JoinFetch 注释并将其设置为延迟加载?这两个注释似乎有冲突 - 它不能同时与父实体一起获取,并且只有在访问时才获取 - 如果您希望延迟获取它,请删除其上的 JoinFetch 注释。
  • 感谢 cmets。我删除了 JoinFetch,但延迟加载不起作用。据我了解,对于 ManyToOne,我必须在 EclipseLink 中启用动态编织:wiki.eclipse.org/EclipseLink/UserGuide/JPA/… 但是,我通过继承解决了这个问题;

标签: java spring-boot jpa eclipselink


【解决方案1】:

对于@ManyToOne 中的延迟加载,我必须在 EclipseLink 中启用动态编织: http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving

我通过继承解决了这个问题; 我创建了没有关系的基本实例;

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class FacultyBase {

  @Id
  @GeneratedValue
  private Long id;

  private String name;

  @Column(name = "university_id", nullable = false)
  private Long universityId;

}

和有关系的实例

@Entity
public class Faculty extends Faculty {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "university_id", insertable = false, updatable = false, nullable = false)
    private University university;

}

因此,在 Specialty 实例中,我使用 FacultyBase 而不是 Faculty

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-15
    • 2016-01-18
    • 1970-01-01
    • 2016-03-08
    • 2019-03-09
    • 2021-06-30
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多