英文:
JPA nested object LAZY FETCH returns only first object
问题
我有以下内容。
@Data
@Getter
@Setter
@Accessors(fluent = false, chain = true)
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@MappedSuperclass
@Slf4j
class Base {
private Timestamp createdTime;
private Timestamp modifiedTime;
private String createdBy;
private String modifiedBy;
private Boolean deleted = false;
}
@Getter
@Setter
@Builder
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "account")
@SQLDelete(sql = "UPDATE account SET deleted = true WHERE account_id = ?")
@Where(clause = "deleted=false")
class Account {
@Id
@EqualsAndHashCode.Include()
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long accountId;
@Builder.Default
@OneToMany(fetch = FetchType.LAZY, mappedBy = "account", cascade = {CascadeType.ALL})
private Set<Collab> collaborators = new HashSet<>(0);
private String objId;
}
class Collab {
@Id
@EqualsAndHashCode.Include()
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long collabId;
private String email;
private String role;
@JsonBackReference
@JoinColumn(name = "accountId")
@ManyToOne(fetch = FetchType.EAGER)
private Account account;
}
public interface AccountRepo {
Optional<Account> findByObjId(String objId);
}
尽管在数据库中单个帐户有多个合作伙伴,但当我检查AccountRepo.findByObjId
(或findAll
)方法的响应时,任何帐户对象中的collaborators
只有1个元素。我漏掉了什么? PS: @EqualsAndHashCode.Include()
是来自 Lombok。
英文:
I have the following.
@Data
@Getter
@Setter
@Accessors(fluent = false, chain = true)
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@MappedSuperclass
@Slf4j
class Base {
private Timestamp createdTime;
private Timestamp modifiedTime;
private String createdBy;
private String modifiedBy;
private Boolean deleted = false;
}
@Getter
@Setter
@Builder
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "account")
@SQLDelete(sql = "UPDATE account SET deleted = true WHERE account_id = ?")
@Where(clause = "deleted=false")
class Account {
@Id
@EqualsAndHashCode.Include()
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long accountId;
@Builder.Default
@OneToMany(fetch = FetchType.LAZY, mappedBy = "account", cascade = {CascadeType.ALL})
private Set<Collab> collaborators = new HashSet<>(0);
private String objId;
}
class Collab {
@Id
@EqualsAndHashCode.Include()
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long collabId;
private String email;
private String role;
@JsonBackReference
@JoinColumn(name = "accountId")
@ManyToOne(fetch = FetchType.EAGER)
private Account account;
}
public interface AccountRepo {
Optional<Account> findByObjId(String objId);
}
Even though there are multiple collab for a single account in the DB.
When I inspect the response of AccountRepo.findByObjId (or findAll) method, only 1 element is inside collaborators
for any account object. What am I missing?
PS: @EqualsAndHashCode.Include()
is from lombok
答案1
得分: 2
当您检查AccountRepo.findByObjId或findAll的响应时,您可能只会看到协作者集合中的一个元素,因为惰性加载机制会按需加载相关的Collab实体。如果在检索Account对象后访问协作者集合,它应该会触发从数据库加载关联的Collab实体。
尝试通过实现一个类似这样的协作者的getter方法:
public Set<Collab> getCollaborators() {
return collaborators;
}
之后,您可以像这样访问协作者:
Optional<Account> accountOptional = accountRepo.findByObjId(objId);
if (accountOptional.isPresent()) {
Account account = accountOptional.get();
Set<Collab> collaborators = account.getCollaborators(); // 加载协作者
}
英文:
When you inspect the response of AccountRepo.findByObjId or findAll, you may only see one element inside the collaborators set because the lazy-loading mechanism loads the related Collab entities on-demand. If you access the collaborators set after retrieving an Account object, it should trigger the loading of the associated Collab entities from the database.
Try by implementing a getter method for collaborators like this
public Set<Collab> getCollaborators() {
return collaborators;
}
after that you can access the collaborators like this
Optional<Account> accountOptional = accountRepo.findByObjId(objId);
if (accountOptional.isPresent()) {
Account account = accountOptional.get();
Set<Collab> collaborators = account.getCollaborators(); // Load collaborators
}
答案2
得分: 0
在BaseClass中,我有以下的注解,这导致了HashCode/Equals的问题,最终影响了Set中的项目。
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
英文:
Turns our I had the following annotation in the BaseClass which was causing the issue with Hashcode/Equals and eventually the items in the Set.
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论