Java 在不使用MongoTemplate的@version注释的情况下设置version属性
我们正在使用Spring.data.mongodb的@Version注释来利用乐观锁定,并使用Java 在不使用MongoTemplate的@version注释的情况下设置version属性,java,spring,spring-data,spring-data-mongodb,mongotemplate,Java,Spring,Spring Data,Spring Data Mongodb,Mongotemplate,我们正在使用Spring.data.mongodb的@Version注释来利用乐观锁定,并使用mongoTemplate.save(T entity)保存实体 由于我们使用的是六边形体系结构,其中具体的MongoTemplate实现位于基础架构模块中,而域模型位于“核心”模块中,因此我们还需要在其中添加对spring.data.mongodb的maven依赖项,以便使用@Version注释: @Document("basket") public class Basket { @Id
mongoTemplate.save(T entity)
保存实体
由于我们使用的是六边形体系结构,其中具体的MongoTemplate
实现位于基础架构模块中,而域模型位于“核心”模块中,因此我们还需要在其中添加对spring.data.mongodb的maven依赖项,以便使用@Version
注释:
@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属性。我在深入研究后自己找到了答案。我取消了
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);
}
}
}
不幸的是,fieldNamingStrategy类属性是私有的,没有getter,因此需要将该字段向上拉并复制它
从理论上讲,如果需要,现在也可以用自己的注释替换其他注释,例如
@Id
我在深入研究后自己找到了它。我取消了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);
}
}
}
不幸的是,fieldNamingStrategy类属性是私有的,没有getter,因此需要将该字段向上拉并复制它
理论上,如果需要,现在也可以用自己的注释替换其他注释,例如@Id