Zabon
Zabon

Reputation: 245

Hibernate - Spring - ConstraintViolationException - UniqueConstraint

I'm trying to make some fixtures for my Profile model but every time I'm trying to save it "again" after I did an update, I get this message: nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

This is my Profile class:

@Entity
@Data
@Builder
@ToString(of = {"birthday", "discordId", "description", "spokenLanguages"})
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "profile", uniqueConstraints = @UniqueConstraint(columnNames = "discordId"))
public class Profile implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idProfile;
    private Date birthday;  
    @Column(name="discordId", insertable=true, updatable=false)
    private String discordId;
    private String description;

    @ElementCollection(fetch = FetchType.EAGER)
    private Set<String> spokenLanguages = new LinkedHashSet<String>();

    @JsonIgnore
    @OneToMany(fetch = FetchType.EAGER)
    private Set<ProfileGame> profileGames = new LinkedHashSet<>();

    @OneToOne(mappedBy = "profile", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
    private User user;

    @ManyToOne
    private TimeSlot timeSlot;

}

Here is the call:

@Order(7)
    @Test
    void fillProfileGame() {
        List<Profile> profileList = this.profileRepository.findAll();
        for (Profile profile : profileList) {           
            List<Game> gameList = this.gameRepository.findAll();
            Collections.shuffle(gameList);
            int rndNbGame = new Random().ints(1, 5).findFirst().getAsInt();
            for (int i = 1; i <= rndNbGame; i++) {
                int rndLevel = new Random().ints(1, 100).findFirst().getAsInt();
                int rndRanking = new Random().ints(1, 3000).findFirst().getAsInt();             
                Game rndGame = gameList.get(0);
                gameList.remove(0);
                ProfileGame profileGames = new ProfileGame(profile, rndGame, "level-" + rndLevel,
                        "ranking-" + rndRanking);
                this.profileGameRepository.save(profileGames);
                this.gameRepository.save(rndGame);
            }       
            this.profileRepository.save(profile);
        }       
    }

So what I understand is that Hibernate won't let me update this object because it has a unique contraint field ?

How do we proceed when we want a field to be unique and still being able to update other fields ?

Upvotes: 0

Views: 964

Answers (1)

Sidharth
Sidharth

Reputation: 182

From the code snippet, what I see is that there are some unique constraints applied on the column 'discordId'.

@Table(name = "profile", uniqueConstraints = @UniqueConstraint(columnNames = "discordId"))

and

@Column(name="discordId", insertable=true, updatable=false)
private String discordId;

As you can see, there is a parameter 'updatable' which is set to false. Therefore, when you are trying to update an already existing object, hibernate is throwing UniqueConstraintViolationException.

To fix this, set 'updatable=true' or remove it altogether and it should work fine.

@Column(name="discordId", insertable=true, updatable=true)
private String discordId;

Upvotes: 1

Related Questions