我的应用程序中的Hibernate(3.6.1.Final)表现很奇怪,我现在非常绝望。这种行为在MariaDB 10.1和Amazon RDS上都会发生。
在一定数量的成功持久化操作之后(大约总共5k次),Hibernate会触发一个:
SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
根据堆栈跟踪,Hibernate试图将实体中的外键填充为一个负值,从而违反了FK约束( FK的目标表没有这样的主键值)。
奇怪的是:
- 仅在成功持续约5k次后才会发生
- 提交此类数量的持久操作后,即使重新启动应用程序(以及数据库),也会发生错误。唯一的解决方法是清除数据库并重复。
- 无论负载是连续的、批处理的、单线程的还是多线程的都会出现错误。
@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Charge extends Entry {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "totalId")
private Amount total;
//....
以下是 Amount 实体中主键的定义:
@GeneratedValue
@Id
@Column(nullable = false)
private Integer pk;
//....
我的问题是:
- 为什么FK会出现无效的负值?(被FK指向的主键设置为自动增量,从1开始,之前的所有插入都按照这个规则完美执行)
- 为什么错误只在大约5k次持久化后才发生?
- 为什么即使重新启动应用程序也无法解决问题?数据库没问题,因为在应用程序外手动插入有效的FK值可以正常工作。
我怀疑是Hibernate以及它如何管理DB上的自动增量。有很多关于这个主题的帖子,但没有一个符合我的特定情况(只有在一定使用量后才出现错误)。
最后注意:在DB上,auto_increment最初设置为1。在错误出现之前的所有初始持久性(Amount实体)都具有从1开始的递增PK:(1,2,3,...)。那么,为什么在一段时间后Hibernate会出现负数(与FK不兼容)?
非常感谢您的帮助。
最好 G.
-1
吗?还是一些随机的负值?绝对值是否与任何现有的外键匹配? - Dragan Bozanovicpk
int(11) NOT NULL AUTO_INCREMENT, - user2248614