同一张表有多个业务实体绑定时,每个实体页面点击删除按钮时,抛出乐观锁异常

container.getAllInstance 并不执行实体映射。建议你先确定 PersonAccident 实体是什么情况下创建的。
可以这样,在 BaseUuidEntity 实体的构造器中设置条件断点, 设置条件只对 PersonAccident 类型的实体挂起, 这样你就能看到 PersonAccident 被创建时的堆栈信息,观察一下这个实体的创建是哪个方法调用的。

感谢提供思路,在BaseUuidEntity中设置条件断点后,在PowerAccident页面中新增时没有触发断点,新增后选中该条PowerAccident数据,点击删除,会触发条件断点,条件设置为this instanceof PersonAccident

也就是说,还是删除的过程中出的问题,查看堆栈发现确实是截图408行,执行到最后是:image
这一步创建实例时,错误的创建了实例的类型

这个问题的根源在于同一张数据库表在系统里有多个实体类匹配。

同样类似的情景存在于扩展实体的时候, 比如我创建myUser实体继承cuba的user实体,也会造成一个系统里 同一张表匹配多个实体。 但是这种case下不会报你这个错误。 唯一不同在于 cuba扩展实体的时候会给数据库表加一个dtype字段来标记“正确”的实体类型, 比如下面的例子,用cip$ExtDdcuiMessage扩展了ddcui$Message,新增一个project_id字段, cuba会生成如下改动:

alter table DDCUI_MESSAGE add column PROJECT_ID uuid ^
alter table DDCUI_MESSAGE add column DTYPE varchar(100) ^
update DDCUI_MESSAGE set DTYPE = 'cip$ExtDdcuiMessage' where DTYPE is null ^

很明显这个dtype发挥了作用。
顺着这个思路, 把你的数据库表加上DTYPE字段,针对不同的数据设置不同的dtype,看是否能解决问题。先手动设置不同的dtype,看是否有用。
如果时间不够,可以查源码,看看DTYPE在哪些地方起了作用也许有帮助。

这个问题没遇到过,上面都是一些思路,酌情采纳 :grinning:

我又看了下Dtype是用于DiscriminatorValue,也许通过@DiscriminatorValue可以帮上忙。
但是还要多查查。

谢谢静静,@DiscriminatorValue是实体继承中的注解吧,指定子类的type字段的值。

下午采用Ray提到的实体继承的模式尝试了一下,应该是解决了实体类匹配的问题,但是还是出现乐观锁错误,有趣的是,这次乐观锁错误提示中,是提示当前删除的实体类了。
父类代码:

@Table(name = “SFM_ACCIDENT”)
@Entity(name = “sfm_Accident”)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = “accident_type”, discriminatorType = DiscriminatorType.STRING)
public class Accident extends StandardEntity{……}

子类代码:即通过@DiscriminatorValue指定类型值

@Entity(name = “sfm_A”)
@DiscriminatorValue(“1”)
public class A extends Accident {……}

在页面删除A时报错:

org.eclipse.persistence.exceptions.OptimisticLockException
Exception Description: The object [com.test.entity.test.A-b5ef1f80-5a90-d652-9cbb-5f468567f8a8 [managed]] cannot be updated because it has changed or been deleted since it was last read.

目前我也在排查原因中

我在英文论坛看了下用 InheritanceType.SINGLE_TABLE 方案应该是可行的。

你的表有没有什么外键关联到别处又关联回来,然后用了DeletePolicy.CASCADE策略的 :joy:

我把示例代码 https://github.com/cuba-guides/cuba-petclinic-data-model-entity-inheritance 扩展了一下,仿照你的多个实体对应同一个table。 基类是A,子类是catVisit和dogVisit,然后从实体探查创建、删除都没问题。 这个方向是没错的。

你也可以先在实体探查做删除,看看实体探查会不会报错。

好的,感谢,我再排查一下原因

实体继承已解决,刚才是我们代码的问题。感谢几位的参与!

2 个赞