Spring Data JPA 中的嵌套接口投影

问题描述 投票:0回答:1

我正在开发一个基于 Spring Boot 的应用程序,我想利用基于接口的投影,因为我想从 mysql 数据库中选择部分列。

我有一个 CourseEntity.java 类,与 ModuleEntity.java 具有一对多关系

@Entity
@Table(name = "course")
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CourseEntity extends BaseEntity {

  private String title;
  private String subTitle;
  private String longDescription;
  private String shortDescription;
  
  @OneToMany(mappedBy = "course", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, orphanRemoval = true)
  private List<ModuleEntity> modules = new ArrayList<>();
  ...
  ...
  ...
  // 100 More Fields
}


@Entity
@Table(name = "module")
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ModuleEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  protected Long id;

  private String name;
  private String shortDescription;
  private String longDescription;
  private String thumbnailPath;

  @Column(name = "course_id", insertable = false, updatable = false)
  private Long courseId;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "course_id", updatable = false)
  private CourseEntity course;
  ...
  ...
  // 50 more fields
}

我的班级有很多字段,您可以在课程表中看到 100 个字段,在模块表中看到 50 个字段。甚至还有数据类型为 JSON 的列,其中仅包含大量静态数据。我想创建一个简单的 API,它应该只返回课程 id、标题、子标题,包括仅包含模块 id 名称的模块数据。对于这个API,我不想选择整个课程和模块实体,因为网络上会有大量数据传输未被使用。

为此,我创建了 2 个用于投影目的的界面

public interface CourseLookup {
    Long getId();
    String getTitle();
    String getSubTitle();
    List<ModuleLookup> getModules();
}

public interface ModuleLookup {

    Long getId();
    String getName();
}

现在我不知道如何将模块相关数据映射到“getModules()”方法。在 JPQL 中,我无法使用模块的别名。当我尝试使用以下查询时,我得到的 getModules() 为 null

@Query("Select distinct c.id as id, c.title as title, c.subTitle as subTitle, m.id as moduleId, m.name as moduleName From CourseEntity Left Join c.modules m Where id = :id")
Optional<CourseLookup> getData(Long id);

当我尝试使用这样的别名进行映射时,休眠会从数据库中选择模块的所有列

@Query("Select distinct c.id as id, c.title as title, c.subTitle as subTitle, m as modules From CourseEntity Left Join c.modules m Where id = :id")
Optional<CourseLookup> getData(Long id);

此外,当使用第二种方法时,尽管使用了 unique 关键字,我还是得到了重复的记录。我无法映射嵌套投影

spring-boot hibernate jpa spring-data-jpa interface
1个回答
0
投票

一些想法(没有可用的IDEA/DB):

  1. 我会特别清楚并写下
    .... c.id = :id
  2. 关于您的第二个查询:模块中的重复项在哪里?尝试在
    m.id
    上进行区分。
© www.soinside.com 2019 - 2024. All rights reserved.