【问题标题】:MySQL auto-increment set to 22378; new record assigned id = 1MySQL自动增量设置为22378;分配 id = 1 的新记录
【发布时间】:2013-10-04 01:00:32
【问题描述】:

MySQL (InnoDB) 自动增量似乎配置正确,但调用

em.persist(entry)

导致错误:

异常 [EclipseLink 4002] (Eclipse Persistence Services 2.5.0.v20130507 3faac2b):org.eclipse.persistence.exceptions.DatabaseException

内部异常:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 键“P​​RIMARY”的重复条目“1” 错误代码:1062

要持久化的实体(Entry),使用主键entry_id,通过它加入到库存表中。

@Entity
@Table(name="entries")
public class Entry implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 8144553107778486945L;

/*
 * PRIMARY KEY & ID FOR THE CASE
 */
@Id
@Column(name="ENTRY_ID")
@GeneratedValue(strategy = GenerationType.AUTO)        // was TABLE
    private Long entry_id;

@Version
private Integer version;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "entry",
        cascade={CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name="entry_id")
private List<InventoryEntry> inventory =
    new ArrayList<InventoryEntry>();

运行查询:

select max(entry_id) FROM entries

产量:

max(entry_id)
22377

跑步:

show table status from chambers like ‘entries’

在 MySQL 命令行客户端中显示下一个自增数是:

22378

问题:为什么将 id = 1 分配给新记录?

据我了解,自动增量在数据库启动时重置为 max(id) + 1,查询结果证实确实如此。我应该补充一点,该表以前使用过:strategy = GenerationType.TABLE,并且使用此策略首先出现了 Duplicate Entry '1' 错误(这就是我采用自动增量策略的原因)。我已经删除了序列表。我还删除了数据库并从 Java 类重新生成模式,从备份中重新填充数据。一切都无济于事。

Describe ENTRIES 显示 entry_id 行的配置为:

字段:ENTRY_ID, 类型:大整数(20), 空:否, 关键:PRI, 默认值:空, 额外:自动增量

该行被索引为 PRIMARY。因此,一切似乎都井然有序。

我应该补充一点,这个 Web 应用程序利用了运行在 Glassfish 4.0 社区服务器(最近从 Glassfish 3.1.2.2 嵌入式服务器升级)中的 MySQL InnoDB 数据库。 Eclipse Kepler 是 Windows 7 64 位平台上的 IDE。

我已经用尽了我微薄能力的极限。任何帮助将不胜感激。

【问题讨论】:

  • 显示你的插入字符串?

标签: java mysql jpa eclipselink


【解决方案1】:

您看到这个问题是因为 MySQL 没有为行生成 ID,EclipseLink 是。您可以尝试使用GenerationType.IDENTITY 来强制JPA 使用标识列(这会强制从数据库中重新读取以更新Java 对象),或者您可以恢复之前的状态;不知道EclipseLink是如何实现GenerationType.AUTO的。

【讨论】:

  • 感谢您的解释。我还在学习如何使用注释。
  • @RobertPeake 您没有对注释做任何错误,只是注释的含义(告诉 JPA 提供者如何创建值)与您想要发生的不匹配(告诉它使用数据库的自动分配)。
  • 在 EclipseLink 中自动默认生成表。
【解决方案2】:

使用@GeneratedValue(strategy = GenerationType.IDENTITY) 而不是@GeneratedValue(strategy = GenerationType.AUTO)

因为:

IDENTITY 策略还在提交期间为每个新实体对象生成一个自动值。不同之处在于每个类型层次结构都管理一个单独的标识生成器,因此生成的值仅在每个类型层次结构中是唯一的。

【讨论】:

  • 感谢您和@chrylis 的快速响应!该解决方案就像一个魅力。
猜你喜欢
  • 2012-07-08
  • 2011-12-18
  • 2014-05-06
  • 1970-01-01
  • 2012-02-22
  • 2015-12-22
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多