【问题标题】:Fetch child entities when finding by a normal field in Spring Data JPA通过 Spring Data JPA 中的普通字段查找时获取子实体
【发布时间】:2017-07-07 18:30:01
【问题描述】:

我正在使用 Spring Data JpaRepository 来查找与特定字段匹配的实体列表。考虑以下代码 sn-p:

实体:

@Entity
@Table(name = "master")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Master implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    @Column(name = "id", nullable = false)
    private Long Id;

@NotNull
    @Column(name = "user_id", nullable = false)
    private String userId;

@OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="id", referencedColumnName="id", insertable=false, updatable=false)
    private Details Details;

Spring Data 自定义 JpaRepository:

public interface MasterRepository extends JpaRepository<Master,Long> {

    List<Master> findMasterByUserId(String userId);

}

当我使用 findBookingMasterByUserId 存储库方法来查找具有特定用户 ID 的所有记录时,我得到了 Master 实体的列表,但我没有得到具有 id 作为外键的 Details 实体它。

但是,当我使用开箱即用的 findAll 方法 JpaRepository 但使用自定义 findMasterByUserId 存储库方法时,我得到了所有依赖实体,不会急切地获取子实体。

我们将不胜感激任何类型的帮助。谢谢!

【问题讨论】:

  • 试过@Query?
  • @Rossi 我不想编写自定义查询,但想使用 JpaRepository 本身。

标签: spring hibernate spring-data spring-data-jpa


【解决方案1】:

您可以在您的 repo 中使用@EntityGraph 来急切地获取相关数据:

@EntityGraph(attributePaths = {"details"})
List<Master> findBookingMasterByUserId(String userId); 

附:不要忘记将“详细信息”字段更改为details

【讨论】:

  • 我一定会试试这个,如果它有效,请告诉你。
  • @gschambial ,如果答案对您有帮助,请不要忘记接受/投票。
【解决方案2】:

您的实体名称是“Master”而不是“booking_master”。

将您的方法更改为:

List<Master> findByUserId(String userId);

有关 JPA 的查询创建机制的更多信息,请参阅下面的 spring 文档。

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/

或者,

@Query("SELECT m FROM Master m WHERE m.userId = :userId")
List<Master> findByUserId(@Param("userId") String userId);

从方法名称生成查询是一种查询生成策略,其中调用的查询是从查询方法的名称派生的。

我们可以按照以下规则创建使用此策略的查询方法:

  • 我们的查询方法的名称必须以下列之一开头 前缀:find...By、read...By、query...By、count...By 和 get...By。
  • 如果我们想限制返回查询结果的数量,我们可以添加 第一个 By 字之前的 First 或 Top 关键字。如果我们想 得到多个结果,我们必须附加可选的数字 First 和 Top 关键字的值。例如,findTopBy, findTop1By、findFirstBy 和 findFirst1By 都返回第一个实体 与指定的搜索条件匹配。
  • 如果我们想选择唯一的结果,我们必须添加 Distinct 第一个 By 字之前的关键字。例如,findTitleDistinctBy 或 findDistinctTitleBy 表示我们要选择所有唯一的标题 从数据库中找到。
  • 我们必须在第一个之后添加我们查询方法的搜索条件 言传身教。我们可以通过组合属性来指定搜索条件 带有受支持关键字的表达式。
  • 如果我们的查询方法指定了x个搜索条件,我们必须加上x 方法参数给它。换句话说,方法的数量 参数必须等于搜索条件的数量。还, 方法参数必须以与搜索相同的顺序给出 条件。

【讨论】:

  • 谢谢@Tanmay。我在问题中错误地写了 findBookingMasterByUserId 而不是 findMasterByUserId。
  • 其实我不想写查询,而是想用spring自己的JpaRepository来执行任务。
  • 你只写 findByUserId 而不是 findMasterByUserId。返回类型本身指定要返回的 Master 列表。尝试使用 Spring 自己的方法的第一个答案。 List findByUserId(String userId);
  • 如何回答这个问题?我理解这个问题是关于急切/延迟加载的?
猜你喜欢
  • 2019-01-07
  • 2019-07-16
  • 2023-03-19
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
相关资源
最近更新 更多