无需使用MongoTemplate的@Version注解即可设置版本属性。

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

我们使用Spring.data.mongodb的@Version注解来使用乐观的锁定和保存实体。mongoTemplate.save(T entity).

由于我们使用的是六边形结构,其中混凝土 MongoTemplate 的实现位于基础架构模块中,而域模型则位于 "核心 "模块中,因此我们需要在其中加入一个针对spring.data.mongodb的maven依赖关系,以便使用 @Version 注解。

@Document("basket")
public class Basket {


  @Id
  BasketId id;

  @Version
  long documentVersion;

}

现在我们要把整个Spring的依赖关系去掉。core 模块,因为我们要提取 core 为LIB-jar,并在另一个项目中使用它(不使用spring)。对于 @Document@Id 这里的部分很容易,因为 MongoTemplate 似乎不痛不痒地察觉到我们 BasketId (因为它被称为 "id"),MongoTemplate提供了一个集合名称,当摆脱了 @Document. 然而,这对于 documentVersion 并简单地将其更名为 version 也不工作。

所以我想知道如何在不使用MongoTemplate注解的情况下使用版本属性。

java spring spring-data spring-data-mongodb mongotemplate
1个回答
0
投票

我自己挖空心思的想出了这个问题。我取消了使用 org.springframework.data.annotation.@Version 无论在 core 项目,并用我自己的注解替换了它,叫做 @EnabledOptimisticLocking. 为了使 spring.data.mongodb 提防 @Version 你需要做以下工作。

public class CustomVersionAnnotationMappingContext extends MongoMappingContext {

private static final FieldNamingStrategy DEFAULT_NAMING_STRATEGY = PropertyNameFieldNamingStrategy.INSTANCE;

private FieldNamingStrategy fieldNamingStrategy = DEFAULT_NAMING_STRATEGY;

@Override
public MongoPersistentProperty createPersistentProperty(Property property, BasicMongoPersistentEntity<?> owner,
        SimpleTypeHolder simpleTypeHolder) {
    return new CustomVersionAnnotationPersistentProperty(property, owner, simpleTypeHolder, fieldNamingStrategy);
}

@Override
public void setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
    super.setFieldNamingStrategy(fieldNamingStrategy);
    this.fieldNamingStrategy = fieldNamingStrategy == null ? DEFAULT_NAMING_STRATEGY : fieldNamingStrategy;
}

class CustomVersionAnnotationPersistentProperty extends CachingMongoPersistentProperty {

    /**
     * Creates a new {@link CachingMongoPersistentProperty}.
     *
     * @param property
     * @param owner
     * @param simpleTypeHolder
     * @param fieldNamingStrategy
     */
    public CustomVersionAnnotationPersistentProperty(Property property,
            MongoPersistentEntity<?> owner,
            SimpleTypeHolder simpleTypeHolder,
            FieldNamingStrategy fieldNamingStrategy) {
        super(property, owner, simpleTypeHolder, fieldNamingStrategy);
    }

    @Override
    public boolean isVersionProperty() {
        return isAnnotationPresent(EnableOptimisticLocking.class);
    }
}
}

然后简单地将其初始化为Bean,然后再创建一个默认的Bean。

@Bean
public MongoMappingContext mongoMappingContext(@Autowired CustomConversions customConversions) throws ClassNotFoundException {

    MongoMappingContext mappingContext = new CustomVersionAnnotationMappingContext();
    mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
    mappingContext.setAutoIndexCreation(true);
    mappingContext.afterPropertiesSet();

    return mappingContext;
}

不幸的是,fieldNamingStrategy类属性是私有的,没有getter, 因此需要把这个字段拉起来,然后复制它。

理论上,现在如果需要的话,也可以用自己的注解替换其他注解,例如 @Id.

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