我们使用Spring.data.mongodb的@Version注解来使用乐观锁定,并使用mongoTemplate.save(T entity)保存实体。
由于我们使用的是六边形架构,其中具体的MongoTemplate实现位于基础设施模块中,而域模型位于“核心”模块中,为了使用@Version注释,我们还需要在其中放置对spring.data.mongodb的maven依赖:
@Document("basket")
public class Basket {
@Id
BasketId id;
@Version
long documentVersion;
}现在我们希望摆脱整个core模块中的Spring依赖,因为我们希望将core提取为LIB-jar并在另一个项目中使用它(该项目不使用spring)。对于这里的@Document和@Id部分来说,这很容易,因为MongoTemplate似乎不费力地检测我们的BasketId (因为它被称为"id"),并且MongoTemplate在去掉@Document时提供了一个集合名称。但是,这对于documentVersion是假的,简单地将其重命名为version也不起作用。
所以我想知道在不使用MongoTemplate注解的情况下使用version属性。
发布于 2020-06-10 23:48:42
我在深入研究后自己发现了这一点。我在core项目中停止了org.springframework.data.annotation.@Version的使用,并用我自己的名为@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。
https://stackoverflow.com/questions/62289368
复制相似问题