У меня есть класс Challenge
, который имеет отношение много к одному с классом User
. Это однонаправленный, так это выглядит следующим образом:Весна данных JPA вызывает EntityExistsException с каскадным сохранением
@Entity
@Table(name = "UserTable")
public class User {
@Id
private String userId;
}
@Entity
@Table(name = "ChallengeTable")
public class Challenge {
@Id
private String challengeId;
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "userId")
private User user;
}
Я использую Spring Data JPA
, и когда я использую save
метод из CRUDRepository
на Challenge
объекта, я хочу, чтобы упорствовать прилагаемую пользователю, если пользователь еще не существует и объединяет пользователя в старый пользователь, если он уже существует.
Я использую метод findOne(String id)
в UserRepository
, чтобы получить пользователь, используя userId
, и это пользователь я устанавливаю в Challenge
.
Она каскады прекрасно, если пользователь не существует, но когда я пытаюсь сохранить его с предварительно существующим пользователем я получаю исключение:
javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [com.mywebsite.model.User#zk9moo78sx685g6o9yphegdx6lpoll9x]
я не уверен, что я я делаю неправильно здесь. Изменение CascadeType
на ALL
ничего не меняет. Пытаться полностью удалить CascadeType
и вручную сохранить пользователя сначала тоже не работает. Это дает мне ошибку:
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: com.mywebsite.model.Challenge.user -> com.mywebsite.model.User
Это кажется, имеет место, когда выходит из сделки (как у меня есть класс обслуживания слой с аннотацией @Transactional
).
Если я вынимаю аннотацию @Transactional
и сохраняю ее вручную, кажется, все работает нормально. (Я все еще хочу, чтобы каскадное сохраняет и операции на уровне услуг, хотя.)
Достав @Transactional
и пытаются использовать каскадный сохраняет сбой с SQLIntegrityConstraintViolationException
исключения, потому что кажется, что User
становится отдельностоящим лицом и пытается сохраняться он заново, но этот первичный ключ уже существует, поэтому он терпит неудачу.
Может ли кто-нибудь помочь мне понять, что здесь происходит, и помочь мне получить каскадное сохранение работы с транзакциями в Spring Data JPA
?
Можете ли вы опубликовать свой метод обслуживания? – lunr
У вас есть методы hashcode и equals, созданные для сущностей? –
Мне не хватало hashcode и равнялось на двух сущностях, но исправление не помогло решить проблему. – CorayThan