Hibernate OneToOne отношения

У меня есть два объекта сохранения: User и UserDetail. У них отношения один к одному. Я использую аннотации гибернации. Но я получаю в своей базе данных несколько объектов пользовательской информации для одного и того же пользователя. Видимо, мои знания аннотаций Hibernate не настолько хороши, чтобы решить эту проблему.

Класс Пользователь:

@Entity
@Table(name = "USER")
public class User {

   @Id
   @GeneratedValue
   @Column(name = "ID")
   private Long id; 

   @Column(name = "NAME")
   private String name; 

   @Column(name = "PASSWORD")
   private String password;

   @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
   private UserDetail userDetail;

   // setters and getters

}

Класс UserDetail:

@Entity
@Table(name = "USER_DETAIL")
public class UserDetail {  

   @OneToOne
   @JoinColumn(name = "USER_ID")
   private User user;

   // other fields

}

Я использую это в своем коде следующим образом:

UserDetail userDetail = new UserDetail();
userDetail.setInfo(info);
userDetail.setUser(seventhUser);
hibernateTemplate.saveOrUpdate(userDetail);

И все работает исправно. Вот какая у меня таблица USER_DETAIL: USER_DETAIL table

Но когда я пытаюсь изменить информацию о пользователе, я получаю неправильное поведение. Я получаю следующую таблицу после того, как я снова установил информацию о пользователе:

UserDetail newUserDetail = new UserDetail();
newUserDetail.setInfo(newInfo);
newUserDetail.setUser(seventhUser);
hibernateTemplate.saveOrUpdate(newUserDetail);

введите здесь описание изображения

Почему одни и те же два объекта информации соответствуют одному пользователю?? У меня отношения Один-к-одному. Как я могу этого избежать? Что я делаю не так?


person Michael    schedule 09.10.2012    source источник


Ответы (1)


Если вы хотите изменить существующий UserDetail, вы должны установить его идентификатор или получить его из сеанса и изменить. В противном случае Hibernate считает, что это новый файл, который необходимо сохранить, поскольку у него нет идентификатора.

UserDetail existingUserDetail = session.get(UserDetail.class, theUserDetailId);
existingUserDetail.setInfo(newInfo);

Чтобы убедиться, что вы не сохраняете два экземпляра UserDetail для одного и того же пользователя, вы должны добавить уникальное ограничение в столбец USER_ID таблицы базы данных UserDetail.

person JB Nizet    schedule 09.10.2012
comment
Я могу как-то заставить Hibernate проверять согласованность данных на уровне базы данных? Чтобы не было ситуации, когда несколько объектов относятся к одному пользователю, но отношением один к одному - person Michael; 09.10.2012
comment
Чтобы убедиться, что вы не сохраняете два экземпляра UserDetail для одного и того же пользователя, вам следует добавить уникальное ограничение в столбец USER_ID таблицы базы данных UserDetail - person JB Nizet; 09.10.2012