Hibernate @OneToMany关系级联选项不起作用



我设计了简单的1:N模式,Account(1):AccountProfileImage(N).

以下代码为实体代码。

// Account.java
@Entity
@Table(name = "account")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
public class Account {
@GeneratedValue
@Id
@Column(name = "id")
private Long id;
@Column(name = "email", nullable = false)
private String email;
@Column(name = "password", nullable = false)
private String password;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
@CreatedDate
@Column(name = "created_at")
private LocalDateTime createdAt;
@OneToMany(mappedBy ="account",cascade = CascadeType.ALL)
private final List<AccountProfileImage> profileImages= new ArrayList<>();

@Builder
public Account(String email,String firstName,String lastName,String password){
this.email=email;
this.firstName=firstName;
this.lastName=lastName;
this.password=password;
}
}
// AccountProfileImage.java
@Entity
@Table(name = "account_profile_image")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@EntityListeners(AuditingEntityListener.class)
public class AccountProfileImage {
@Id
@GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "account_id")
private Account account;
@Column(name = "image_url")
private String imageURL;
@CreatedDate
@Column(name = "created_at")
private LocalDateTime createdAt;
@Builder
public AccountProfileImage (Account account,String imageURL){
this.account=account;
// this.account.addProfileImage(this);
this.imageURL=imageURL;
}
}

,这是AccountProfileRepository代码的测试代码。

@Test
@Rollback(value = false)
public void saveAccountProfileImageTest() throws Exception {
// given
Account account = Account.builder()
.email("user@email.com")
.firstName("user")
.lastName("user")
.password("1234")
.build();

AccountProfileImage profileImage = AccountProfileImage.builder()
.account(account)
.imageURL("pathToURI")
.build();

AccountProfileImage profileImage2 = AccountProfileImage.builder()
.account(account)
.imageURL("pathToURI2")
.build();
accountRepository.save(account);

// when
List<AccountProfileImage> images = profileImageRepository.findAllByAccount_IdOrderByCreatedAtDesc(1L);
// then
// this assertion fail
assertThat(images.size()).isEqualTo(2);
}

我希望找到的图像列表,其大小为2,因为我在Account实体类中添加CscadeType.ALL,并且在创建AccountProfileImage对象时,我在AccountProfileImage对象中设置帐户成员变量。

this.account =账户;

我做错了什么吗?


我在帐户实体和2行测试代码中添加下面的方法,然后它工作得很好。我每次都要这么做吗?是否存在其他更好的方法或最佳实践?

// Account Entity
public void addProfileImages(AccountProfileImage image){
this.profileImages.add(image);
}
// test code
account.addProfileImages(profileImage);
account.addProfileImages(profileImage2);
accountRepository.save(account);
// when
List<AccountProfileImage> images = profileImageRepository.findAllByAccount_IdOrderByCreatedAtDesc(1L);
// then
// this assertion pass
assertThat(images.size()).isEqualTo(2);

在双向关系中,必须在关系的两端定义关联。为了避免任何问题,您可以更新助手addProfileImage(..)方法,将AccountProfileImage添加到列表中,并将映像的account属性设置为当前帐户。这是最佳实践,因为这样,helper方法将在双向关系的两端建立关联。

public void addProfileImages(AccountProfileImage image){
this.profileImages.add(image); // Add image to profileImages
image.setAccount(this); // Set account property to the current account
}

测试:

@Test
@Rollback(value = false)
public void saveAccountProfileImageTest() throws Exception {
// given
Account account = Account.builder()
.email("user@email.com")
.firstName("user")
.lastName("user")
.password("1234")
.build();

AccountProfileImage profileImage = AccountProfileImage.builder()
.imageURL("pathToURI")
.build();

AccountProfileImage profileImage2 = AccountProfileImage.builder()
.imageURL("pathToURI2")
.build();
// Setup association
account.addProfileImage(profileImage);
account.addProfileImage(profileImage2);
accountRepository.save(account);

// when
List<AccountProfileImage> images = profileImageRepository.findAllByAccount_IdOrderByCreatedAtDesc(1L);
// then
// this assertion fail
assertThat(images.size()).isEqualTo(2);
}

最新更新