【问题标题】:Spring / Hibernate - StaleStateException thrown when deleting entitySpring / Hibernate - 删除实体时抛出 StaleStateException
【发布时间】:2021-06-09 07:43:31
【问题描述】:

我的一个实体在尝试删除它时抛出了 StaleStateException。有问题的代码:

@RestController
@RequestMapping("/cycles")
public class DeleteCycleController {
  @DeleteMapping("{cycleId}")
  @ResponseStatus(HttpStatus.NO_CONTENT)
  public void deleteCycleById(@PathVariable("cycleId") UUID cycleId, Principal principal) {
// cycleRepository extends CrudRepository
    cycleRepository.deleteById(new CycleId(cycleId));
//    deleter.deleteCycle(new CycleId(cycleId));
  }
}

抛出以下内容:

org.springframework.orm.ObjectOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; statement executed: HikariProxyPreparedStatement@716092925 wrapping delete from cycle where id='c4c1428e-c296-4199-85f6-8ef16e6999c9'::uuid; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; statement executed: HikariProxyPreparedStatement@716092925 wrapping delete from cycle where id='c4c1428e-c296-4199-85f6-8ef16e6999c9'::uuid

以下是失败前的休眠日志:

2021-03-11 20:34:11.532 DEBUG 55483 --- [nio-8080-exec-7] org.hibernate.SQL                        : requestId=b53dd96089f748cf942fc46867d32fb5, requestMethod=DELETE, correlationId=b53dd96089f748cf942fc46867d32fb5, requestURI=/cycles/c4c1428e-c296-4199-85f6-8ef16e6999c9, userId=5ae11e82-f8df-4fad-ae10-1aa57423ba31, orgId=c7389774-9afa-452b-aa1c-74e7b18bc04d : select cycle0_.id as id1_0_0_, cycle0_.attributes as attribut2_0_0_, cycle0_.created_at as created_3_0_0_, cycle0_.cycle_type_id as cycle_ty4_0_0_, cycle0_.description as descript5_0_0_, cycle0_.end_time as end_time6_0_0_, cycle0_.start_time as start_ti7_0_0_, cycle0_.end_location as end_loca8_0_0_, cycle0_.last_modified_at as last_mod9_0_0_, cycle0_.name as name10_0_0_, cycle0_.organization_id as organiz11_0_0_, cycle0_.start_location as start_l12_0_0_ from cycle cycle0_ where cycle0_.id=?
Hibernate: select cycle0_.id as id1_0_0_, cycle0_.attributes as attribut2_0_0_, cycle0_.created_at as created_3_0_0_, cycle0_.cycle_type_id as cycle_ty4_0_0_, cycle0_.description as descript5_0_0_, cycle0_.end_time as end_time6_0_0_, cycle0_.start_time as start_ti7_0_0_, cycle0_.end_location as end_loca8_0_0_, cycle0_.last_modified_at as last_mod9_0_0_, cycle0_.name as name10_0_0_, cycle0_.organization_id as organiz11_0_0_, cycle0_.start_location as start_l12_0_0_ from cycle cycle0_ where cycle0_.id=?
2021-03-11 20:34:11.533 TRACE 55483 --- [nio-8080-exec-7] o.h.type.descriptor.sql.BasicBinder      : requestId=b53dd96089f748cf942fc46867d32fb5, requestMethod=DELETE, correlationId=b53dd96089f748cf942fc46867d32fb5, requestURI=/cycles/c4c1428e-c296-4199-85f6-8ef16e6999c9, userId=5ae11e82-f8df-4fad-ae10-1aa57423ba31, orgId=c7389774-9afa-452b-aa1c-74e7b18bc04d : binding parameter [1] as [OTHER] - [c4c1428e-c296-4199-85f6-8ef16e6999c9]
2021-03-11 20:34:11.542 DEBUG 55483 --- [nio-8080-exec-7] org.hibernate.SQL                        : requestId=b53dd96089f748cf942fc46867d32fb5, requestMethod=DELETE, correlationId=b53dd96089f748cf942fc46867d32fb5, requestURI=/cycles/c4c1428e-c296-4199-85f6-8ef16e6999c9, userId=5ae11e82-f8df-4fad-ae10-1aa57423ba31, orgId=c7389774-9afa-452b-aa1c-74e7b18bc04d : delete from cycle where id=?
Hibernate: delete from cycle where id=?
2021-03-11 20:34:11.542 TRACE 55483 --- [nio-8080-exec-7] o.h.type.descriptor.sql.BasicBinder      : requestId=b53dd96089f748cf942fc46867d32fb5, requestMethod=DELETE, correlationId=b53dd96089f748cf942fc46867d32fb5, requestURI=/cycles/c4c1428e-c296-4199-85f6-8ef16e6999c9, userId=5ae11e82-f8df-4fad-ae10-1aa57423ba31, orgId=c7389774-9afa-452b-aa1c-74e7b18bc04d : binding parameter [1] as [OTHER] - [c4c1428e-c296-4199-85f6-8ef16e6999c9]

还有 Cycle 实体:

@javax.persistence.Entity
@Accessors(fluent = true)
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@TypeDefs({@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)})
public class Cycle {
  @Id private UUID id;
  private CycleName name;
  private CycleDescription description;
  private UUID cycleTypeId;
  private UUID organizationId;
  private Instant createdAt;
  private Instant lastModifiedAt;

  @Type(type = "jsonb")
  private Map<String, Object> attributes;

  private CycleDuration duration;

  @Column(columnDefinition = "Geometry", nullable = true)
  private Geometry startLocation; 

  private Geometry endLocation;

  @OneToMany(mappedBy = "cycleId", cascade = CascadeType.ALL, orphanRemoval = false)
  @Getter(AccessLevel.PRIVATE)
  @Setter(AccessLevel.PUBLIC)
  private List<CycleEntityMapping> entities = new ArrayList<>();
  
  ...
}

关于可能出现什么问题的任何想法?另一个(更简单的)实体删除得很好。

不确定它是否是 OneToMany 引起的问题,但我尝试更改级联类型、孤儿删除和获取类型,但没有成功。否则会不会是值对象造成的?请注意,更新实体工作正常 - 它只是在删除时失败。

【问题讨论】:

  • 你传递给 repo 的“new CycleId”是什么?
  • 我们将 UUID 包装在对象中,在内部循环存储库调用 cycleJPARepository.deleteById(cycleId.id()); 其中 cycleId.id() 返回 UUID
  • 异常表示数据库中不存在该记录。记录还在吗?它在哪里起作用,还有 UUID 作为 PK 使用的吗?
  • 经过进一步调查,似乎是由删除前触发器引起的。触发器将删除的行复制到另一个表中。删除触发器可以解决问题。不知道为什么触发器会导致这个问题
  • 刚刚进一步调查 - 结果是触发器将其复制到存档表,但由于错误(return new 而不是return old)而没有从现有表中删除。将其更改为 return old 可以解决问题

标签: java postgresql spring-boot hibernate jpa


【解决方案1】:

在这种情况下,它是由删除前触发器中的错误引起的。触发器中有一个错误导致该行未被删除:

CREATE OR REPLACE FUNCTION trigger_delete_row_backup()
    RETURNS trigger AS
$BODY$
    BEGIN
INSERT INTO deleted_cycle values (OLD.*);
    RETURN NEW;
    -- should actually be RETURN OLD
    END;
$BODY$
   language PLPGSQL;

一旦触发器被修复,问题就解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2011-06-22
    相关资源
    最近更新 更多