java - JPA EclipseLink 与 @TableGenerator。为什么事务回滚后id赋的值不为空?

标签 java jakarta-ee jpa eclipselink

我有以下实体:

@Entity
@Table(name = "sales", schema = "cust_tables")
@Multitenant(MultitenantType.TABLE_PER_TENANT)
@TenantTableDiscriminator(contextProperty = "customer_schema", type = TenantTableDiscriminatorType.SCHEMA)
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Sale implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "Sale")
    @TableGenerator(name = "Sale", schema = "thehub", allocationSize = 5)
    @Column(name = "id", unique = true, nullable = false, updatable = false)
    @XmlElement
    private Long id;

在持久操作期间,我可能会故意允许事务在乐观锁定失败期间回滚。

然而,我对 JPA/EclipseLink 在这种情况下的行为感到惊讶。正如预期的那样,JPA 将序列中的一个值分配给 id。但是,在回滚期间,该值不会被“删除”。然后,下次我尝试保留时,id 的值已经存在。 JPA 跳过从序列中提取新数字并尝试保留该实体。

我因 SQL 完整性约束异常而失败:

Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130226-e0971b1): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '51' for key 'PRIMARY'
Error Code: 1062

我做错了什么?

最佳答案

当 JPA 事务失败时,所有对象都会分离。您无法重新提交交易。

您需要创建一个新的持久性上下文,并且需要重新创建对象,或者如果您想使用现有对象,请仔细合并到新的持久性上下文中并清空它们的 id。此外,对于更新的任何对象,您将需要恢复其版本字段。

JPA 不提供重新提交交易的简单方法。 EclipseLink 的 native API 提供 commitAndResumeOnFailure(),但这不会公开给 JPA。也许记录一个增强请求以获得某种选项,以允许在 JPA 中重新提交失败的事务。

关于java - JPA EclipseLink 与 @TableGenerator。为什么事务回滚后id赋的值不为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15767252/

相关文章:

jpa - Spring数据存储库如何查询包含子字符串的String的ElementCollection

java - Spring Data JPA @Table 注释工作

java - 在 Struts2 操作中通过 @OneToMany 关系映射两个实体失败

java - 回到基础: Generics in Method Sig

java - 如何在java中使两个二维数组相等?

javascript - 电子邮件邮件字段验证

xml - 什么是最普遍、最稳定和面向 future 的 B2B 协议(protocol)(最好是开放的)?

java - 手动安装时无法在 ubuntu 14.04 中设置 JAVA_HOME 变量

java - 无限的游戏背景

java - 在Java中,是否可以使用某种while循环(或任何东西)来确定输入提示的数量?