英文:
ERROR: update or delete on table "users" violates foreign key constraint "fkoixwfhgxuda232r3m5llu7few" on table "addresses"
问题
以下是代码的翻译部分:
我有两个实体Users和Addresses,它们之间有OneToMany的映射从Users到Addresses。
```java
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
private Long id;
@Email
@Column(unique = true)
private String email;
@OneToMany(mappedBy = "user", orphanRemoval = true, fetch = FetchType.LAZY)
@JsonManagedReference(value = "addresses")
private Set<Address> addresses;
}
@Entity
@Table(name = "addresses")
public class Address {
@Id
@GeneratedValue
private Long id;
@NotBlank
@ColumnTransformer(
read = "PGP_SYM_DECRYPT(title::bytea, current_setting('my.dbsecretkey'))",
write = "PGP_SYM_ENCRYPT (?, current_setting('my.dbsecretkey'))"
)
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "owner_email", referencedColumnName = "email")
@JsonBackReference(value = "addresses")
private User user;
@Column(name = "owner_email", insertable=false, updatable=false)
private String owner_email;
@ElementCollection
private Set<String> sharedWithUsers;
}
我想要更新用户的电子邮件,如下所示
public void changeEmail(String email, String password, String newEmail) throws AuthenticationException {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(email, password));
var user = userRepository.findByEmail(email).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
user.setEmail(newEmail);
userRepository.save(user);
} catch (BadCredentialsException e) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
}
但当我这样做时,我遇到了这个错误:org.postgresql.util.PSQLException: ERROR: update or delete on table "users" violates foreign key constraint "fkoixwfhgxuda232r3m5llu7few" on table "addresses" Detail: Key (email)=(first@mail.com) is still referenced from table "addresses".
我已经尝试向User实体添加CascadeType.ALL,但没有帮助。请帮助我。
英文:
I have two entities Users and Addresses with OneToMany mapping from Users.
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
private Long id;
@Email
@Column(unique = true)
private String email;
@OneToMany(mappedBy = "user", orphanRemoval = true, fetch = FetchType.LAZY)
@JsonManagedReference(value = "addresses")
private Set<Address> addresses;
}
@Entity
@Table(name = "addresses")
public class Address {
@Id
@GeneratedValue
private Long id;
@NotBlank
@ColumnTransformer(
read = "PGP_SYM_DECRYPT(title::bytea, current_setting('my.dbsecretkey'))",
write = "PGP_SYM_ENCRYPT (?, current_setting('my.dbsecretkey'))"
)
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "owner_email", referencedColumnName = "email")
@JsonBackReference(value = "addresses")
private User user;
@Column(name = "owner_email", insertable=false, updatable=false)
private String owner_email;
@ElementCollection
private Set<String> sharedWithUsers;
}
I want to update user's email like so
public void changeEmail(String email, String password, String newEmail) throws AuthenticationException {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(email, password));
var user = userRepository.findByEmail(email).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
user.setEmail(newEmail);
userRepository.save(user);
} catch (BadCredentialsException e) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
}
But when I do it I get this error: org.postgresql.util.PSQLException: ERROR: update or delete on table "users" violates foreign key constraint "fkoixwfhgxuda232r3m5llu7few" on table "addresses"
Detail: Key (email)=(first@mail.com) is still referenced from table "addresses".
I've already tried to add CascadeType.ALL to User's entity, but it does not helped.
Please help me.
答案1
得分: 1
The error says that the email from the table 'users' is also used as a foreign key in the table 'addresses'. This has been modeled in the entity Address with the annotation:
@JoinColumn(name = "owner_email", referencedColumnName = "email")
This has been done for reason. As a check of data integrity - if the user changes his/her email then the corresponding entry 'owner_email' should be changed as well.
Solution - update both fields in your service class before calling save. Like this:
user.setEmail(newEmail);
for (String address : user.getAddresses()) {
address.setOwnerEmail(newEmail);
}
userRepository.save(user);
英文:
The error says that the email from the table 'users' is also used as a foreign key in the table 'addresses'. This has been modeled in the entity Address with the annotation:
@JoinColumn(name = "owner_email", referencedColumnName = "email")
This has been done for reason. As a check of data integrity - if the user changes his/her email then the corresponding entry 'owner_email' should be changed as well.
Solution - update both fields in your service class before calling save. Like this:
user.setEmail(newEmail);
for (String address : user.getAddresses()) {
address.setOwnerEmail(newEmail);
}
userRepository.save(user);
答案2
得分: 0
I have updated one line of code in your changeEmail
method. Here's the translated portion:
public void changeEmail(String email, String password, String newEmail) throws AuthenticationException {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(email, password));
var user = userRepository.findByEmail(email).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
user.setEmail(newEmail);
for (Address address : user.getAddresses()) {
address.setUser(null);
}
userRepository.save(user);
} catch (BadCredentialsException e) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
}
If you are deleting the user, you can add the @OnDelete
in your user entity:
@OneToMany(mappedBy = "user", orphanRemoval = true, fetch = FetchType.LAZY)
@JsonManagedReference(value = "addresses")
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<Address> addresses;
英文:
i have update one line of code in your changeEmail method go and try, it will work
public void changeEmail(String email, String password, String newEmail) throws AuthenticationException {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(email, password));
var user = userRepository.findByEmail(email).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
user.setEmail(newEmail);
for (Address address : user.getAddresses()) {
address.setUser(null);
}
userRepository.save(user);
} catch (BadCredentialsException e) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
}
if you are deleting the user you can add the @OnDelete in your user entity
@OneToMany(mappedBy = "user", orphanRemoval = true, fetch = FetchType.LAZY)
@JsonManagedReference(value = "addresses")
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<Address> addresses;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论