Spring - 获取加载惰性元素的实体页面
Spring - get a page of entity with lazy elements loaded
我对 Spring 很陌生。
我正在尝试将页面 return 发送到我的前端。
AppUser 与 Role 实体有惰性关联。
我收到一个未能延迟初始化角色集合的错误。
做了很多研究,但我没有得到这个问题。
让我们看看代码:
AppUser 实体:
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "app_user")
public class AppUser {
@Id
@GeneratedValue
@Column(name = "user_id")
private UUID userId;
@Column(name = "user_first_name")
private String userFirstName;
@Column(name = "user_last_name")
@NonNull
private String userLastName;
@Column(name = "matricule")
private String matricule;
@Column(name = "email_address")
private String emailAddress;
@Column(name = "password")
private String password;
@EqualsAndHashCode.Exclude
@ManyToOne
@JoinColumn(name = "grade_id")
private Grade grade;
@EqualsAndHashCode.Exclude
@ManyToMany
@JoinTable(name = "user_role_association", joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "application_role_id"))
private List<AppRole> appRoles;
控制器方法:
@GetMapping(path = "user", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Page<AppUser>> getUserPage(@AuthenticationPrincipal UserDetail user,
@RequestParam("page") int page,
@RequestParam("size") int size,
@RequestParam(value = "sortDirection",
required = false) String sortDirection,
@RequestParam(value = "sortField", required =
false) String sortField) {
log.info(String.format("User %s getting list of all users", user.getUsername()));
try {
final Page<AppUser> response = appUserService.getAll(page, size,sortDirection,
sortField);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("Error fetching user page", e);
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Error fetching data");
}
}
服务方式:
public Page<AppUser> getAll(int page,
int size,
String sortDirection,
String sortField) {
Pageable pageable;
Sort sort;
// sorting & pagination
if (sortField != null && !sortField.isEmpty()) {
sort = Sort.by(sortField);
if (sortDirection != null && sortDirection.equals("desc")) {
sort = sort.descending();
}
} else {
sort = Sort.by("matricule").descending();
}
pageable = PageRequest.of(page, size, sort);
return appUserRepository.findAllAppUserWithAllProperties(pageable);
}
存储库
@Repository
public interface AppUserRepository extends JpaRepository<AppUser, UUID> {
Optional<AppUser> findByUserId(UUID uuid);
AppUser findByMatricule(String matricule);
@Query(value = "SELECT u FROM AppUser u LEFT JOIN FETCH u.appRoles WHERE u.matricule =
:matricule")
AppUser findAppUserWithAppRolesByMatricule(String matricule);
@Query(value = "SELECT u FROM AppUser u LEFT JOIN u.appRoles")
Page<AppUser> findAllAppUserWithAllProperties(Pageable pageable);
}
查看日志我可以看到查询运行:
SQL - select appuser0_.user_id as user_id1_0_, appuser0_.email_address as email_ad2_0_,
appuser0_.grade_id as grade_id7_0_, appuser0_.matricule as matricul3_0_, appuser0_.password as
password4_0_, appuser0_.user_first_name as user_fir5_0_, appuser0_.user_last_name as
user_las6_0_ from rixheim.app_user appuser0_ left outer join rixheim.user_role_association
approles1_ on appuser0_.user_id=approles1_.user_id left outer join rixheim.application_role
approle2_ on approles1_.application_role_id=approle2_.application_role_id order by
appuser0_.matricule desc limit ?
所以我想我还没有办法检索完整的对象,但我现在真的卡住了。
如果您能在这方面提供帮助,我们将不胜感激。
谢谢。
延迟关联是故意的还是可以更改?如果可以:
@EqualsAndHashCode.Exclude
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role_association", joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "application_role_id"))
private List<AppRole> appRoles;
如果没有,您可以通过显式调用它来触发它们的加载,例如通过获取它们 appUser.getAppRoles()
。它不漂亮,但应该可以。
终于找到方法了。
@EntityGraph(attributePaths = {"appRoles", "grade"})
@Query(value = "FROM AppUser appuser")
Page<AppUser> findAllAppUserWithAllProperties(Example example, Pageable
pageable);
听起来使用 EntityGraph 将保持延迟加载,除非我们专门调用该查询。
我对 Spring 很陌生。
我正在尝试将页面 return 发送到我的前端。 AppUser 与 Role 实体有惰性关联。
我收到一个未能延迟初始化角色集合的错误。
做了很多研究,但我没有得到这个问题。
让我们看看代码:
AppUser 实体:
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "app_user")
public class AppUser {
@Id
@GeneratedValue
@Column(name = "user_id")
private UUID userId;
@Column(name = "user_first_name")
private String userFirstName;
@Column(name = "user_last_name")
@NonNull
private String userLastName;
@Column(name = "matricule")
private String matricule;
@Column(name = "email_address")
private String emailAddress;
@Column(name = "password")
private String password;
@EqualsAndHashCode.Exclude
@ManyToOne
@JoinColumn(name = "grade_id")
private Grade grade;
@EqualsAndHashCode.Exclude
@ManyToMany
@JoinTable(name = "user_role_association", joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "application_role_id"))
private List<AppRole> appRoles;
控制器方法:
@GetMapping(path = "user", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Page<AppUser>> getUserPage(@AuthenticationPrincipal UserDetail user,
@RequestParam("page") int page,
@RequestParam("size") int size,
@RequestParam(value = "sortDirection",
required = false) String sortDirection,
@RequestParam(value = "sortField", required =
false) String sortField) {
log.info(String.format("User %s getting list of all users", user.getUsername()));
try {
final Page<AppUser> response = appUserService.getAll(page, size,sortDirection,
sortField);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("Error fetching user page", e);
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Error fetching data");
}
}
服务方式:
public Page<AppUser> getAll(int page,
int size,
String sortDirection,
String sortField) {
Pageable pageable;
Sort sort;
// sorting & pagination
if (sortField != null && !sortField.isEmpty()) {
sort = Sort.by(sortField);
if (sortDirection != null && sortDirection.equals("desc")) {
sort = sort.descending();
}
} else {
sort = Sort.by("matricule").descending();
}
pageable = PageRequest.of(page, size, sort);
return appUserRepository.findAllAppUserWithAllProperties(pageable);
}
存储库
@Repository
public interface AppUserRepository extends JpaRepository<AppUser, UUID> {
Optional<AppUser> findByUserId(UUID uuid);
AppUser findByMatricule(String matricule);
@Query(value = "SELECT u FROM AppUser u LEFT JOIN FETCH u.appRoles WHERE u.matricule =
:matricule")
AppUser findAppUserWithAppRolesByMatricule(String matricule);
@Query(value = "SELECT u FROM AppUser u LEFT JOIN u.appRoles")
Page<AppUser> findAllAppUserWithAllProperties(Pageable pageable);
}
查看日志我可以看到查询运行:
SQL - select appuser0_.user_id as user_id1_0_, appuser0_.email_address as email_ad2_0_,
appuser0_.grade_id as grade_id7_0_, appuser0_.matricule as matricul3_0_, appuser0_.password as
password4_0_, appuser0_.user_first_name as user_fir5_0_, appuser0_.user_last_name as
user_las6_0_ from rixheim.app_user appuser0_ left outer join rixheim.user_role_association
approles1_ on appuser0_.user_id=approles1_.user_id left outer join rixheim.application_role
approle2_ on approles1_.application_role_id=approle2_.application_role_id order by
appuser0_.matricule desc limit ?
所以我想我还没有办法检索完整的对象,但我现在真的卡住了。
如果您能在这方面提供帮助,我们将不胜感激。
谢谢。
延迟关联是故意的还是可以更改?如果可以:
@EqualsAndHashCode.Exclude
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role_association", joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "application_role_id"))
private List<AppRole> appRoles;
如果没有,您可以通过显式调用它来触发它们的加载,例如通过获取它们 appUser.getAppRoles()
。它不漂亮,但应该可以。
终于找到方法了。
@EntityGraph(attributePaths = {"appRoles", "grade"})
@Query(value = "FROM AppUser appuser")
Page<AppUser> findAllAppUserWithAllProperties(Example example, Pageable
pageable);
听起来使用 EntityGraph 将保持延迟加载,除非我们专门调用该查询。