7

I have entity user:

@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

Base object is: @MappedSuperclass public class 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;
}

}

The proble is, when I try to UPDATE object, I am getting errors:

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'

For update entity I am using:

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

I am dont know why I am getting this error, how can I update my object? Thank you for your help.

EDIT: I update:

User u = em.find(persistedType, id); //get user by ID
u.getSetOfRequesSet().add(requestSet); //add one otem to set
userDap.merge(u); //save
6
  • That doesn't define HOW you attempt to update an object. Where do you get the object from? em.find() ? query? then is it detached? then you update some field(s) whilst detached? Commented Aug 13, 2016 at 8:19
  • Is there a transaction including both loading and updating of the user? If not I believe the entity gets detached so that Hibernate maybe does not know any more that it is the same as the one in database. Does it work with such a transaction or if you load the entity before merging in "save"? Commented Aug 13, 2016 at 8:30
  • Are there multiple RequestSets with same ID? Commented Aug 13, 2016 at 8:32
  • Yes. I want save requestSet with id 1 for more users. Commented Aug 13, 2016 at 8:33
  • If you just do a find then do an update you have no need to do a "merge", since the objects will be "managed" ... assuming all of that is in a single transaction. What is "requestSet" ? Is it already persistent, or a new object? Commented Aug 13, 2016 at 8:44

1 Answer 1

5

It looks like your update duplicates entries in the set (em.merge). To prevent the duplication you should merge set explicitly. Do as following.

  1. Add method merge to User:

    protected User merge(User other) {
        // Just assign all data members(2 examples here)
        setEmail(other.getEmail());
        ....
        setSetOfRequesSet(other.getSetOfRequesSet());
        ...            
    }
    
  2. Prepare an updated object instance:

    User updated = em.find(persistedType, id); //get user by ID
    updated.getSetOfRequesSet().add(requestSet); //add one item to set
    
  3. Update the existing db entity:

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

Not necessary to cal to em.merge after the update, since save will be just done at the end of a transaction.

You can find the explanation here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.