【问题标题】:The duplicate key value JPA重复键值 JPA
【发布时间】:2016-03-13 10:19:58
【问题描述】:

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

13:47:26.191 [http-nio-8080-exec-1] 错误 o.h.e.jdbc.spi.SqlExceptionHelper - 违反主键约束“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。

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

【问题讨论】:

    标签: java spring hibernate jpa


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        您可以使用自定义逻辑从数据库中获取最新的 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;
        }
        

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

          • 我应该怎么做?我使用了这个:'@Id @SequenceGenerator(name="id_generator", sequenceName="SEQUENCE_NAME", allocationSize=1) @GeneratedValue(generator="id_generator", strategy=GenerationType.SEQUENCE)' 但结果相同
          • stackoverflow.com/questions/2595124/… ,参考链接希望它能解决您的问题。
          猜你喜欢
          • 2011-09-21
          • 1970-01-01
          • 2018-11-09
          • 1970-01-01
          • 2015-07-13
          • 2019-02-06
          • 2016-10-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多