ERROR: update or delete on table "users" violates foreign key constraint "fkoixwfhgxuda232r3m5llu7few" on table "addresses"

huangapple go评论65阅读模式
英文:

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 = &quot;users&quot;)
public class User {
    @Id
    @GeneratedValue
    private Long id;

    @Email
    @Column(unique = true)
    private String email;

    @OneToMany(mappedBy = &quot;user&quot;, orphanRemoval = true, fetch = FetchType.LAZY)
    @JsonManagedReference(value = &quot;addresses&quot;)
    private Set&lt;Address&gt; addresses;
}
@Entity
@Table(name = &quot;addresses&quot;)
public class Address {
    @Id
    @GeneratedValue
    private Long id;

    @NotBlank
    @ColumnTransformer(
            read = &quot;PGP_SYM_DECRYPT(title::bytea, current_setting(&#39;my.dbsecretkey&#39;))&quot;,
            write = &quot;PGP_SYM_ENCRYPT (?, current_setting(&#39;my.dbsecretkey&#39;))&quot;
    )
    private String title;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = &quot;owner_email&quot;, referencedColumnName = &quot;email&quot;)
    @JsonBackReference(value = &quot;addresses&quot;)
    private User user;

    @Column(name = &quot;owner_email&quot;, insertable=false, updatable=false)
    private String owner_email;

    @ElementCollection
    private Set&lt;String&gt; 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(() -&gt; 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 &quot;users&quot; violates foreign key constraint &quot;fkoixwfhgxuda232r3m5llu7few&quot; on table &quot;addresses&quot;
Detail: Key (email)=(first@mail.com) is still referenced from table &quot;addresses&quot;.

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 = &quot;owner_email&quot;, referencedColumnName = &quot;email&quot;)

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(() -&gt; 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 = &quot;user&quot;, orphanRemoval = true, fetch = FetchType.LAZY)
@JsonManagedReference(value = &quot;addresses&quot;)
@OnDelete(action = OnDeleteAction.CASCADE)
private Set&lt;Address&gt; 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(() -&gt; 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 = &quot;user&quot;, orphanRemoval = true, fetch = FetchType.LAZY)
@JsonManagedReference(value = &quot;addresses&quot;)
@OnDelete(action = OnDeleteAction.CASCADE)
private Set&lt;Address&gt; addresses;

huangapple
  • 本文由 发表于 2023年4月7日 01:00:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75952014.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定