javax.persistence.EntityExistsException: Другой объект с тем же значением идентификатора уже был связан с сеансом
Ответы этого исключения затоплены через Stackoverflow, но ни один из них не соответствует моей проблеме дело. У меня есть две сущности Post
и User
, которые имеют отношение ManyToMany
, но таблица отношений имеет два дополнительных поля: voted_at
и vote
.
Итак, мне нужно иметь дополнительный класс сущностей PostVote
который имел бы EmbeddedId
. PostVote
таблица - это таблица, которая будет содержать user
, проголосовавшего за post
public class PostVote implements Serializable {
@EmbeddedId
private PostVoteId id;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("postId")
@JoinColumn(name = "post_id")
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("userId")
@JoinColumn(name = "user_id")
private User user;
@NotNull
@CreationTimestamp
private LocalDateTime votedAt;
@NotNull
private Boolean vote = true;
public PostVote() {
}
PostVote(Post post, User user) {
this.post = post;
this.user = user;
this.id = new PostVoteId(post.getPostId(), user.getUserId());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PostVote that = (PostVote) o;
return Objects.equals(post, that.post) &&
Objects.equals(user, that.user);
}
@Override
public int hashCode() {
return Objects.hash(post, user);
}
}
PostVoteId
субъект
@Embeddable
public class PostVoteId implements Serializable {
@Column(name = "post_id")
private Integer postId;
@Column(name = "user_id")
private Integer userId;
PostVoteId(Integer postId, Integer userId) {
this.postId = postId;
this.userId = userId;
}
public PostVoteId() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PostVoteId that = (PostVoteId) o;
return Objects.equals(postId, that.postId) &&
Objects.equals(userId, that.userId);
}
@Override
public int hashCode() {
return Objects.hash(postId, userId);
}
}
Я следую Влад Михалча статья . Теперь, чтобы добавить голоса к post
, у меня есть метод addVote
в Post
.
public class Post implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")
@Column(name = "post_id", unique = true, nullable = false)
private Integer postId;
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PostVote> voters = new ArrayList<>();
public void addVote(User user){
PostVote postVote = new PostVote(this, user);
voters.add(postVote);
user.getVotedPosts().add(postVote); //problem here
}
}
Метод обслуживания, который голосует за пост:
Post post = postRepository.findById(postId);
final User user = userRepository.findById(123);
post.addVote(user);
postRepository.save(post);
Приведенный выше код выдает ошибку
javax.persistence.EntityExistsException: другой объект с таким же значением идентификатора уже был связан с сеансом: [com.sample.entities.PostVote # com.sample. сущности. PostVoteId@4ba].
Но , если я удаляю user.getVotedPosts().add(postVote)
(сохраняю одностороннюю двунаправленную связь), тогда он работает нормально.
Существующие решения не помогли. Максимум говорит, что нужно проверить стратегию GenerationType
и реализацию equals
и hashcode
. Но в моем случае оба настроены нормально.