Irakli
Irakli

Reputation: 983

The duplicate key value JPA

I have build a small application on SPring MVC + JPA + SQL Server. For some reasons I had to make some Entity changes in my application and I had to manually migrate some data from old Database to new Database(that have a bit different schema). After I migrated all the data I have such errors:

13:47:26.191 [http-nio-8080-exec-1] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Violation of PRIMARY KEY constraint 'PK__GLJourna__3213E83F741BD595'. Cannot insert duplicate key in object 'dbo.GLEntry'. The duplicate key value is (34903).

This is my entity:

@Entity
public class GLJournalEntry {
@Id @GeneratedValue
private Long id;
private BigDecimal amount;
private Date creationDate;
@OneToOne
@JoinColumn(name = "glAccount_id", nullable = false)
private GLAccount glAccount;
private String notes;
@Enumerated(EnumType.STRING)
private ProductType productTyep;
private Date entryDate;
@Column(nullable = false)
private long transactionID;
@Enumerated(EnumType.STRING)
private EntryType type;
}

My guess is that I receive this error message because of default ID annotation @Id @GeneratedValue.

How can I fix it? how can I generate ID in a way that it automatically got the latest ID from DB?

Upvotes: 2

Views: 4803

Answers (4)

Rishal
Rishal

Reputation: 1538

You can use sequence functionality of the db to get unique ID, which will always be the new and latest one.

Use the link for more informations http://stackoverflow.com/questions/2595124/java-jpa-generators-sequencegenerator

Upvotes: 0

Irakli
Irakli

Reputation: 983

The easiest solution to my problem was to change annotation to the Entity

Changed from : @Id @GeneratedValue to: @Id @GeneratedValue(strategy = GenerationType.AUTO)

Upvotes: 1

Amit Naik
Amit Naik

Reputation: 1073

You can get latest Id from DB by using custom logic. Sample what I did to resolve my issue. It works with Hibernate -

@Id
@Basic(optional = false)
@GeneratedValue(strategy=GenerationType.IDENTITY, generator="GeneratedId")
@GenericGenerator(name="GeneratedId",
                  strategy="....GenerateId"
)
@Column(name = "ID", nullable = false)
private Integer id;

and

import org.hibernate.id.IdentityGenerator;
...
public class GenerateId extends IdentityGenerator {
private static final Logger log = Logger.getLogger(GenerateId.class.getName());

@Override
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
    String prefix = "M";
    Connection connection = session.connection();
    try {

        PreparedStatement ps = connection
                .prepareStatement("SELECT nextval ('seq_stock_code') as nextval");

        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            int id = rs.getInt("nextval");
            String code = prefix + StringUtils.leftPad("" + id,3, '0');
            log.debug("Generated Stock Code: " + code);
            return code;
        }

    } catch (SQLException e) {
        log.error(e);
        throw new HibernateException(
                "Unable to generate Stock Code Sequence");
    }
    return null;
}

Upvotes: 0

MDaniyal
MDaniyal

Reputation: 1097

Try something like this in your Database

CREATE SEQUENCE "ABC"."MY_SEQ" MINVALUE 0 MAXVALUE 2147483647 INCREMENT BY 1 START WITH 9130 CACHE 50 ORDER NOCYCLE ;

Upvotes: 0

Related Questions