首页 > 解决方案 > Hibernate - Spring - ConstraintViolationException - UniqueConstraint

问题描述

我正在尝试为我的个人资料模型制作一些固定装置,但每次我在更新后尝试“再次”保存它时,都会收到以下消息: nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

这是我的个人资料类:

@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;

}

这是电话:

@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);
        }       
    }

所以我的理解是 Hibernate 不会让我更新这个对象,因为它有一个唯一的约束字段?

当我们希望一个字段是唯一的并且仍然能够更新其他字段时,我们如何进行?

标签: spring-boothibernatesql-updateunique-constraint

解决方案


从代码片段中,我看到在“discordId”列上应用了一些独特的约束。

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

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

如您所见,有一个参数“可更新”设置为假。因此,当您尝试更新已经存在的对象时,hibernate 会抛出 UniqueConstraintViolationException。

要解决此问题,请设置 'updatable=true' 或完全删除它,它应该可以正常工作。

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

推荐阅读