2016-08-13 4 views
0

У меня есть объекта пользователя:Как обновить объект, используя спящий режим

@Entity 
@Table(name = "entity_user") 
@AttributeOverride(name = "id", column = @Column(name = "user_id")) 
public class User extends BaseObject implements Serializable { 

    /** 
    * Login, unique 
    */ 
    private String email; 

    private String username; 

    /** 
    * Secret for signing-in 
    */ 
    private String password; 

    /** 
    * Type of user 
    */ 
    private UserType userType; 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    @JoinTable(name = "view_user_to_requestSet", joinColumns = { 
     @JoinColumn(name = "user_id")}, inverseJoinColumns = { 
     @JoinColumn(name = "requestSet_id")}) 
    private Set<RequestSet> setOfRequesSet = new HashSet<>(); 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    @JoinTable(name = "view_user_to_requestSetCreator", joinColumns = { 
     @JoinColumn(name = "user_id")}, inverseJoinColumns = { 
     @JoinColumn(name = "requestSet_id")}) 
    private Set<RequestSet> setOfRequesSetCreator = new HashSet<>(); 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    @JoinTable(name = "view_user_to_userTask", joinColumns = { 
     @JoinColumn(name = "user_id")}, inverseJoinColumns = { 
     @JoinColumn(name = "userTask_id")}) 
    private Set<UserTask> setOfUserTask = new HashSet<>(); 

    public User() { 
    } 

    . 
    . 
..... GET AND SET 

Базовый объект является: @MappedSuperclass общественного класса BaseObject {

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

/** 
* 
* @return true if the entity hasn't been persisted yet 
*/ 
@Transient 
public boolean isNew() { 
    return id == null; 
} 

public Long getId() { 
    return id; 
} 

public void setId(Long id) { 
    this.id = id; 
} 

}

proble есть, когда Я пытаюсь обновить объект, я получаю ошибки:

Exception in thread "Thread-15" org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [UK_5fa729oayn43ynq4v2y4d9qcn]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement 

Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement 

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '5' for key 'UK_5fa729oayn43ynq4v2y4d9qcn' 

Для обновления объекта Я использую:

@Transactional 
public void save(User value){ 
    em.merge(value); 
} 

Я не знаю, почему я получаю эту ошибку, как я могу обновить свой объект? Спасибо за помощь.

EDIT: обновление I:

User u = em.find(persistedType, id); //get user by ID 
u.getSetOfRequesSet().add(requestSet); //add one otem to set 
userDap.merge(u); //save 
+0

Это не определяет, как вы пытаетесь обновить объект. Откуда вы взяли объект? em.find()? запрос? то он отделился? то вы обновляете какое-либо поле (-ы) во время отсоединения? –

+0

Есть ли транзакция, включающая как загрузку, так и обновление пользователя? Если нет, я верю, что объект отделится, так что Hibernate, возможно, уже не знает, что он такой же, как тот, что находится в базе данных. Работает ли она с такой транзакцией или если вы загружаете объект перед слиянием в «Сохранить»? – mm759

+0

Есть ли несколько запросов с одинаковым идентификатором? – mm759

ответ

0

Похоже, ваше обновление дублирует записи в наборе (em.merge). Чтобы предотвратить дублирование, вы должны явно слить набор. Сделайте следующее.

  1. метод Add сливаясь пользователя:

    protected User merge(User other) { 
        // Just assign all data members(2 examples here) 
        setEmail(other.getEmail()); 
        .... 
        setSetOfRequesSet(other.getSetOfRequesSet()); 
        ...    
    } 
    
  2. Подготовка обновленного экземпляра объекта:

    User updated = em.find(persistedType, id); //get user by ID 
    updated.getSetOfRequesSet().add(requestSet); //add one item to set 
    
  3. Обновление существующей БД объект:

    User existing = em.find(persistedType, id); 
    existing.merge(updated); 
    

Не требуется, чтобы cal-em.merge после обновления, так как сохранение будет выполнено только в конце транзакции.

Вы можете найти объяснение here.