user1986745
user1986745

Reputation: 83

Spring with Hibernate: Duplicate entry for key 'PRIMARY'

I have developed a REST- API with Spring Web and Hibernate. I deployed it in two server instances and it runs without any problem for about 5 months. Now it is mostly working but in some periods "MySQLIntegrityConstraintViolationException" with message "Duplicate entry '235648' for key 'PRIMARY'" are thrown (te duplicate id is changing in the exceptions).

The class, for which the exception is thrown, looks like this:

@Entity
@Table(name = "Metadata", catalog = "data")
public class Metadata{
    private Long id;
    private String field1;  
    private String field2;
    //...           

    @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.TABLE)
    public Long getId() {
        return id;
    }
    //More Getters and Setters...
}

There was neither change to java code nor changes on the MySql-database. Do you have any idea why it stopped working properly?

Upvotes: 2

Views: 4902

Answers (2)

Enrique Sime
Enrique Sime

Reputation: 64

@GeneratedValue(strategy = GenerationType.IDENTITY)

worked for me.

Upvotes: 2

Maciej Kowalski
Maciej Kowalski

Reputation: 26522

Most likely, the number of requests which end up creating entities which use that table for id generation has increased.

One of the remedies would be to catch that exception in a parent method and retry (probably this would be some kind of PessimisticLock exception as the id table has to be physically locked while retrieving and updating its content).

Another one would be to increase the allocationSize option, which for you is 50 being the default if no custom set-up is done. You would need to reenter the hibernate default table / columns names as this has been already created in the database:

@Id
@Column(unique = true, nullable = false)
@TableGenerator(
        name="tableGen", 
        table="hibernate_sequences", 
        pkColumnName="sequence_name", 
        valueColumnName="next_val", 
        pkColumnValue="default",
        allocationSize=100 
@GeneratedValue(strategy = GenerationType.TABLE, generator="tableGen")
public Long getId() {
    return id;
}

Here is a nice post which explains the scalability pitfalls of a TABLE generation strategy -> link

Upvotes: 2

Related Questions