美文网首页
Spring Data 使用过程中的小问题

Spring Data 使用过程中的小问题

作者: Antz_H碎碎念 | 来源:发表于2020-03-15 22:23 被阅读0次

一些问题

@Id、@CreatedDate、@LastModifiedDate注解冲突问题

Spring Data 提供了这几个方便的注解,但是在使用的过程中发现了冲突的问题,

  1. @Id如果使用在自定义id的字段上,比如code、name等;
  2. 首先如果想@CreatedDate@LastModifiedDate生效,仅在字段上加上注解时不够的,还需要在启动类Application加上注解@EnableMongoAuditing
  3. @Id@CreatedDate的冲突,如果使用了@Id,那么spring-data-mongo通过调用isNew()认为在mongo中已经存在,导致@CreatedDate不会生效,而@LastModifiedDate会生效;
    isNew()方法在org.springframework.data.mongodb.repository.support.SimpleMongoRepository#save
    采用这种策略检查isNew()
    org.springframework.data.mapping.model.PersistentEntityIsNewStrategy#isNew

解决方式

@Data
@Document(collection = "col_fund")
public class Fund extends AbstractEntity{

    @Id
    private String code;

    private String name;

    private String type;

    @CreatedDate
    private LocalDateTime createdDate = LocalDateTime.now();

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

}

这是另一种取巧的方式,不使用@CreatedDate和@LastModifiedDate注解,有兴趣可以看下源码
org.springframework.data.mongodb.core.MongoTemplate#doInsertBatch

@Configuration
public class MongoCreatedTimeAndLastModifiedTimeEventListener extends AbstractMongoEventListener {

    @Override
    public void onBeforeConvert(BeforeConvertEvent event) {
        Object source = event.getSource();
        if (source instanceof AbstractEntity) {
            LocalDateTime now = LocalDateTime.now();
            AbstractEntity entity = AbstractEntity.class.cast(source);
            entity.setLastModifiedDate(now);
            if (entity.getCreatedDate() == null) {
                entity.setCreatedDate(now);
            }
        }
    }
}

@Version

Long not long.

Spring-Data-Mongo 判断是否是new insert对象

org.springframework.data.mapping.model.PersistentEntityIsNewStrategy#PersistentEntityIsNewStrategy
在isNew()方法中Object value = valueLookup.apply(entity);会根据返回的上面的策略返回Id的值或者version的值来做后续判断是否是new增加的数据。
org.springframework.data.mapping.model.PersistentEntityIsNewStrategy#isNew

总结Spring-Data 判断是否是New的依据

  1. 仅存在@Id时,那么如果@Id对应的字段值为null是否为空;
  2. 当@Id和@Version都存在时,则必须同时都有值,且version > 0 ;
  3. 当@Id和@Version都存在时,但只有@Version有值,报错;
    this.valueType = entity.hasVersionProperty() && !idOnly //
                ? entity.getRequiredVersionProperty().getType() //
                : entity.hasIdProperty() ? entity.getRequiredIdProperty().getType() : null;
    
    @Override
    public boolean isNew(Object entity) {
    
        Object value = valueLookup.apply(entity);
    
        if (value == null) {
            return true;
        }
    
        if (valueType != null && !valueType.isPrimitive()) {
            return value == null;
        }
    
        if (Number.class.isInstance(value)) {
            return ((Number) value).longValue() == 0;
        }
    
        throw new IllegalArgumentException(
                String.format("Could not determine whether %s is new! Unsupported identifier or version property!", entity));
    }
    
OptimisticLockingFailureException

对重试的处理

方案一参考

方案二参考

相关文章

网友评论

      本文标题:Spring Data 使用过程中的小问题

      本文链接:https://www.haomeiwen.com/subject/nxjiehtx.html