重复键值JPA

时间:2016-03-13 10:19:58

标签: java spring hibernate jpa

我在SPring MVC + JPA + SQL Server上构建了一个小应用程序。由于某些原因,我不得不在我的应用程序中进行一些实体更改,我不得不手动将一些数据从旧数据库迁移到新数据库(具有一些不同的模式)。迁移完所有数据后,我遇到了这样的错误:

  

13:47:26.191 [http-nio-8080-exec-1] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - 违反PRIMARY KEY约束' PK__GLJourna__3213E83F741BD595'。无法在对象' dbo.GLEntry'中插入重复键。重复键值为(34903)。

这是我的实体:

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

我的猜测是因为默认ID注释@Id @GeneratedValue而收到此错误消息。

我该如何解决?如何以自动从DB获取最新ID的方式生成ID?

4 个答案:

答案 0 :(得分:1)

我的问题最简单的解决方案是将注释更改为实体

更改自: @Id @GeneratedValue 至: @Id @GeneratedValue(strategy = GenerationType.AUTO)

答案 1 :(得分:0)

您可以使用数据库的序列功能来获取唯一ID,该ID始终是新的ID。

使用此链接获取更多信息http://stackoverflow.com/questions/2595124/java-jpa-generators-sequencegenerator

答案 2 :(得分:0)

在数据库中尝试这样的事情

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

答案 3 :(得分:0)

您可以使用自定义逻辑从DB获取最新的ID。示例我为解决问题所做的工作。它适用于Hibernate -

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

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