【问题标题】:Increment @version when an entity is embedded in an @embeddable当实体嵌入@embeddable 时增加@version
【发布时间】:2022-02-01 20:50:40
【问题描述】:

我知道here 列出了一个类似的问题,但就我自己而言,我没有日期。相反,我有一个嵌入式类,其中包含一个实体。 我有以下实体定义:

Person JPA 实体

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Person {
    @Id
    private int id;

    @CreatedDate
    private OffsetDateTime creationDate;

    @LastModifiedDate
    private OffsetDateTime updatedDate;

    @Version
    private Long version;

    @Embedded
    private ContactAddress contactAddress;
}

ContactAddress JPA 实体

@Embeddable
public class ContactAddress {
    private String notice;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "former_street_id")
    private Street formerStreet;

      @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "new_street_id")
    private Street newStreet;
}

街头 JPA 实体

@Table(name = "p_street")
public class Street  {
    @Id
    private int id;

    private String line1;
    private String line2;
}

Street JPA 实体是 ContactAddress 类的一个字段。当我更新 ContactAddress 实例时,如果更改的是 ContactAddress 的 'notice' 字段,则 Person 实体中的版本会递增。但是,如果我更新任何街道对象字段,则版本不会增加。 原因是我肯定错过了如何通知 auditingEntityListner 在 Person 实体的 updateDate 字段上引发事件。

看起来,有 如果我在嵌入的 ContactAddress 中有 Street 实体,则在 Person 实体和 Street 实体之间创建了断开连接。有没有办法在 JPA 中解决这个问题?

【问题讨论】:

    标签: java spring-boot hibernate jpa spring-data-jpa


    【解决方案1】:

    它按预期工作,因为当您修改 Street 时,您没有修改,只是不同表中的某些实体。 Person(人表)本身没有变化,因此版本没有增加。

    当您修改 ContactAddress 时,由于它是“Person 的一部分”(字面意思是 person 表中的一组列 - 因此是 person),您正在修改行中的 person 条目,因此版本会被提升。

    如果您需要升级版本(我宁愿不),您必须在修改 Street 实体时“触摸”Person。我不知道是否有自动的方法。

    请记住,您的意图是在您修改地址时潜在地增加多人条目的版本,因为地址可能用于多人条目中。

    【讨论】:

    • 我完全同意,当我修改 Street 时,我并没有修改 Person,但我想要一种方式,当我修改 Street、Person 实体时,我希望有一种方法可以将 Street 实体与Person 实体,同时仍将其作为 ContactAddress 中的字段引用。我假设必须有一种方法可以在 Street 表更新时自动触发版本增量。
    • 我不知道(并不意味着没有)。但是,它是单个更新查询,在 contactAddres_id=x 处将版本增加 1。请记住,您不仅应该更新 Person 表中使用相同 id 的所有行,还应该更新其他实体,以保持一致。
    • 谢谢 Antoniosss,我想有办法。我正在研究 OPTIMISTIC_FORCE 作为实现这一目标的一种手段。
    【解决方案2】:

    如果要确保@Version 字段增加,则:

    @PersistenceContext
    private EntityManager em;
    
    public void savePerson(Person p) {
    
        em.lock(p, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
    }
    

    这样人的version字段总是增加。

    注意version 字段会增加 2,如果 Envers 框架知道更改,例如当notice被修改时。

    【讨论】:

      猜你喜欢
      • 2014-08-24
      • 1970-01-01
      • 2019-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-15
      • 2017-03-06
      • 2018-12-08
      相关资源
      最近更新 更多