@PreUpdate 从未调用过 respository.save()

问题描述 投票:0回答:1

在带有

spring-boot-starter-data-jpa
的 spring-boot 3 应用程序中,我有一个实体:

@Entity
public class SomeJson {

  public static final ObjectMapper MAPPER = new ObjectMapper();

  public static final TypeReference<HashMap<String, Object>> MAP_REF = new TypeReference<HashMap<String, Object>>() {};

  // some fields

  public String jsonData;

  @Transient
  public HashMap<String, Object> data = new HashMap<String, Object>();
  
  @Transient
  private int initialHashCode = 0;

  /**
   * Converts JSON-Data to {@link HashMap}.
   */
  @PostLoad
  public void onLoad() {
    try {
      if (StringUtils.isNotEmpty(jsonData))
        data.putAll( MAPPER.readValue(jsonData, MAP_REF) );
    } catch (JacksonException ignore) {}
    initialHashCode = data.hashCode();
  }

  /**
   * Converts {@link HashMap} to JSON-String if dirty.
   */
  @PreUpdate
  public void onSave() {
    System.out.println("**** " + initialHashCode + " == " + data.hashCode() );
    if( initialHashCode == data.hashCode() ) return;
    try {
      jsonData = MAPPER.writeValueAsString(data);
    } catch (JsonProcessingException e) {}
  }
  
}

以及相应的存储库:

@Repository
public interface SomeJsonRepo extends JpaRepository<SomeJson, Long> {}

@PostLoad
工作得很好,但是代码

SomeJson sj = someJsonRepo.findById(42);
sj.data.put("lastSuccessfulExport", System.currentTimeMillis());
// sj.onSave(); (1)
someJsonRepo.save(er);
log.info( "Authentication failed" );

不会触发

@PreUpdate
方法。

如果我取消注释行

(1)
,我会看到
onSave()
被执行了两次:

**** -888829936 == 1673013342
2024-02-19T11:44:27.913+01:00  INFO 18408 --- [nio-8050-exec-1] some.Service : Authentication failed
**** -888829936 == 1673013342

JPA/Hibernate 是否无法确定实例是否脏并且“忘记”触发

@PreUpdate

java spring spring-boot spring-data-jpa
1个回答
0
投票

您可以使用实体监听器

@PreUpdate 回调方法是你可以自定义的

© www.soinside.com 2019 - 2024. All rights reserved.