我们使用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注解的情况下使用版本属性。
我自己挖空心思的想出了这个问题。我取消了使用 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
.