簡體   English   中英

Spring Data JPA在兩個查詢中加載一對一關系

[英]Spring Data JPA loads one to one relationship in two queries

我有以下課程:

@Data
@Entity
@Table(name = "user_info")
public class UserIdentity implements UserDetails {
  @Id
  private Long id;
  private String username;
  private String password;
  private String facebookId;
  private String phoneNumber;
  private Timestamp unblockDate;
  @OneToOne(fetch = FetchType.EAGER, optional = false)
  @Fetch(FetchMode.JOIN)
  @JoinColumn(name = "role_id")
  private Role role;

  }

@Data
@Entity
@Table(name = "role")
public class Role {
  @Id
  private Long id;
  private String name;
  @ManyToMany
  @Fetch(FetchMode.JOIN)
  @JoinTable(name = "role_permission", joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "permission_id", referencedColumnName = "id"))
  private List<Permission> permissions;
}

@Data
@Entity
@Table(name = "permission")
public class Permission {
  @Id
  private Long id;
  private String name;
}

當我查詢用戶身份時,我可以看到在日志中生成的這兩個查詢:

Hibernate: select useridenti0_.id as id1_3_, useridenti0_.facebook_id as facebook2_3_, useridenti0_.password as password3_3_, useridenti0_.phone_number as phone_nu4_3_, useridenti0_.role_id as role_id7_3_, useridenti0_.unblock_date as unblock_5_3_, useridenti0_.username as username6_3_ from user_info useridenti0_ where useridenti0_.facebook_id=?
Hibernate: select role0_.id as id1_1_0_, role0_.name as name2_1_0_, permission1_.role_id as role_id1_2_1_, permission2_.id as permissi2_2_1_, permission2_.id as id1_0_2_, permission2_.name as name2_0_2_ from role role0_ left outer join role_permission permission1_ on role0_.id=permission1_.role_id left outer join permission permission2_ on permission1_.permission_id=permission2_.id where role0_.id=?

但我希望只看到一個查詢。 您能幫我找出我做錯了什么嗎?

更新我正在使用CrudRepositor:

public interface UserIdentityRepository extends CrudRepository<UserIdentity, Long> {
  UserIdentity findByFacebookId(String facebookId);
  UserIdentity findByPhoneNumber(String phoneNumber);
}

並且我注意到了以下事情-如果我使用方法findById()進行搜索, 則按預期進行,但是如果我使用findByPhoneNumber(),則它將不起作用。

您在實體上指定的FetchType僅在EntityManager上使用不接受任何類型查詢的方法時使用。 這是您在調用findById()時有效執行的操作。

但是,如果在使用查詢方法作為findByPhoneNumber()時像Spring Data那樣為您指定查詢,則該查詢將用於確定獲取策略。

但是您可以通過指定實體圖來控制它。 您將在實體類中添加@NamedEntityGraph批注。 還有一個@EntityGraph注釋,用於引用該命名實體圖的查詢方法。

在Github上准備了一個簡單的例子

我用了瑣碎的實體圖

@NamedEntityGraph(name = "joined", includeAllAttributes = true)

它會急切地獲取所有內容,而這實際上可能就是您想要的。

進行一個查詢的唯一方法..並且僅在您的情況下加載UserIdentity是將關系設置為LAZY:

@OneToOne(fetch = FetchType.LAZY, optional = false)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "role_id")
private Role role;

然后在首次使用時以事務方法加載它。

如果符合您的邏輯設計,則可以將Role.id用作主鍵,也可以將其作為外鍵,並使用@MapsId ,如本文所述: link

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM