请使用 'MongoMappingContext#setAutoIndexCreation(boolean)' 或覆盖 'MongoConfigurationSupport#autoIndexCreation()' 以明确说明
Please use 'MongoMappingContext#setAutoIndexCreation(boolean)' or override 'MongoConfigurationSupport#autoIndexCreation()' to be explicit
我浏览了 https://docs.spring.io/spring-data/mongodb/docs/2.2.0.RC1/reference/html/#mapping-usage 和网络上的其他资源,但解决方案对我不起作用。
我正在使用 Spring Boot 2.2。2.RELEASE 和 Spring Data Mongo。在此示例中,在 Model/Pojo 字段级别,我们使用
@Indexed(name = AppConstants.FIRSTNAME_INDEX, direction = IndexDirection.ASCENDING)
private String firstName;
错误:
Please use 'MongoMappingContext#setAutoIndexCreation(boolean)' or override 'MongoConfigurationSupport#autoIndexCreation()' to be explicit.
However, we recommend setting up indices manually in an application ready block. You may use index derivation there as well.
> -----------------------------------------------------------------------------------------
> @EventListener(ApplicationReadyEvent.class)
> public void initIndicesAfterStartup() {
>
> IndexOperations indexOps = mongoTemplate.indexOps(DomainType.class);
>
> IndexResolver resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);
> resolver.resolveIndexFor(DomainType.class).forEach(indexOps::ensureIndex);
> }
> -----------------------------------------------------------------------------------------
按照日志中的建议,我实现了,但我没有看到方法 setAutoIndexCreation。
public class MongoConfig extends AbstractMongoClientConfiguration {
@Override
public MongoClient mongoClient() {
// TODO Auto-generated method stub
return null;
}
@Override
protected String getDatabaseName() {
// TODO Auto-generated method stub
return null;
}
}
在 application.properties 文件中禁用自动索引创建
spring.data.mongodb.auto-index-creation=false
或application.yml文件
spring:
data:
mongodb:
auto-index-creation: false
创建带有@Configuration 注释的class MongoConfiguration
Injetc 这个依赖项
private final MongoTemplate mongoTemplate;
private final MongoConverter mongoConverter;
并添加此方法
@EventListener(ApplicationReadyEvent.class)
public void initIndicesAfterStartup() {
log.info("Mongo InitIndicesAfterStartup init");
var init = System.currentTimeMillis();
var mappingContext = this.mongoConverter.getMappingContext();
if (mappingContext instanceof MongoMappingContext) {
MongoMappingContext mongoMappingContext = (MongoMappingContext) mappingContext;
for (BasicMongoPersistentEntity<?> persistentEntity : mongoMappingContext.getPersistentEntities()) {
var clazz = persistentEntity.getType();
if (clazz.isAnnotationPresent(Document.class)) {
var resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);
var indexOps = mongoTemplate.indexOps(clazz);
resolver.resolveIndexFor(clazz).forEach(indexOps::ensureIndex);
}
}
}
log.info("Mongo InitIndicesAfterStartup take: {}", (System.currentTimeMillis() - init));
}
记住 var 只适用于 java 11+
最终的class,它使用了Lombok
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexResolver;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
@Slf4j
@RequiredArgsConstructor
@Configuration
public class MongoConfiguration {
private final MongoTemplate mongoTemplate;
private final MongoConverter mongoConverter;
@EventListener(ApplicationReadyEvent.class)
public void initIndicesAfterStartup() {
log.info("Mongo InitIndicesAfterStartup init");
var init = System.currentTimeMillis();
var mappingContext = this.mongoConverter.getMappingContext();
if (mappingContext instanceof MongoMappingContext) {
MongoMappingContext mongoMappingContext = (MongoMappingContext) mappingContext;
for (BasicMongoPersistentEntity<?> persistentEntity : mongoMappingContext.getPersistentEntities()) {
var clazz = persistentEntity.getType();
if (clazz.isAnnotationPresent(Document.class)) {
var resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);
var indexOps = mongoTemplate.indexOps(clazz);
resolver.resolveIndexFor(clazz).forEach(indexOps::ensureIndex);
}
}
}
log.info("Mongo InitIndicesAfterStartup take: {}", (System.currentTimeMillis() - init));
}
}
但该解决方案效果不佳,至少在反应式上下文中是这样。此时 mongoMappingContext.getPersistentEntities()
为空。只有auto-index-creation: true
(甚至mongoMappingContext.setAutoIndexCreation(true)
)才能保证索引的创建。
尝试了以下配置,我什至创建了一个自己的 mappingContext bean
@Configuration
public class MongoConfiguration extends AbstractMongoClientConfiguration {
private final AbstractCloudConfig abstractCloudConfig;
@Autowired
public MongoConfiguration(AbstractCloudConfig abstractCloudConfig) {
this.abstractCloudConfig = abstractCloudConfig;
}
@Override
public MongoClient mongoClient() {
return MongoClients.create(MongoClientSettings.builder().build());
}
@Bean
@Override
public MongoDbFactory mongoDbFactory() {
return abstractCloudConfig.connectionFactory().mongoDbFactory();
}
@Bean
public MappingMongoConverter mongoConverter(MappingMongoConverter mongoConverter) {
/*
* For some obscure reason, Spring Mongo does not like hash maps with keys that contain dots '.'.
* We configure to replace dots '.' in maps with some obscure character that does not occur in in keys.
*/
mongoConverter.setMapKeyDotReplacement("~");
return mongoConverter;
}
@Bean
public MongoMappingContext mongoMappingContext() throws ClassNotFoundException {
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(this.getInitialEntitySet());
mappingContext.setSimpleTypeHolder(this.customConversions().getSimpleTypeHolder());
mappingContext.setFieldNamingStrategy(this.fieldNamingStrategy());
mappingContext.setAutoIndexCreation(false);
return mappingContext;
}
@Override
protected String getDatabaseName() {
throw new RuntimeException("This method should not be called");
}
@EventListener(ApplicationReadyEvent.class)
public void initIndicesAfterStartup() throws ClassNotFoundException {
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
this.mongoMappingContext().setAutoIndexCreation(false);
createIndexForEntity(DataSetDefinitionV2.class, mongoTemplate);
createIndexForEntity(ModelConfiguration.class, mongoTemplate);
createIndexForEntity(ScheduleEntity.class, mongoTemplate);
}
private void createIndexForEntity(Class<?> entityClass, MongoTemplate mongoTemplate) throws ClassNotFoundException {
IndexOperations indexOps = mongoTemplate.indexOps(entityClass);
IndexResolver resolver = new MongoPersistentEntityIndexResolver(this.mongoMappingContext());
resolver.resolveIndexFor(entityClass).forEach(indexOps::ensureIndex);
}
}
仍然是警告 comes.I 事件在 application.properties 中尝试了 spring.data.mongodb.auto-index-creation=false,也没有成功
除了 Juan Ibarra 评论外,将此添加到 application.yml 文件对我不起作用:
spring:
data:
mongodb:
auto-index-creation: false
但在 AbstractMongoClientConfiguration 中覆盖 autoIndexCreation() 有效:
@Override
protected boolean autoIndexCreation() {
return false;
}
我浏览了 https://docs.spring.io/spring-data/mongodb/docs/2.2.0.RC1/reference/html/#mapping-usage 和网络上的其他资源,但解决方案对我不起作用。
我正在使用 Spring Boot 2.2。2.RELEASE 和 Spring Data Mongo。在此示例中,在 Model/Pojo 字段级别,我们使用
@Indexed(name = AppConstants.FIRSTNAME_INDEX, direction = IndexDirection.ASCENDING)
private String firstName;
错误:
Please use 'MongoMappingContext#setAutoIndexCreation(boolean)' or override 'MongoConfigurationSupport#autoIndexCreation()' to be explicit.
However, we recommend setting up indices manually in an application ready block. You may use index derivation there as well.
> -----------------------------------------------------------------------------------------
> @EventListener(ApplicationReadyEvent.class)
> public void initIndicesAfterStartup() {
>
> IndexOperations indexOps = mongoTemplate.indexOps(DomainType.class);
>
> IndexResolver resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);
> resolver.resolveIndexFor(DomainType.class).forEach(indexOps::ensureIndex);
> }
> -----------------------------------------------------------------------------------------
按照日志中的建议,我实现了,但我没有看到方法 setAutoIndexCreation。
public class MongoConfig extends AbstractMongoClientConfiguration {
@Override
public MongoClient mongoClient() {
// TODO Auto-generated method stub
return null;
}
@Override
protected String getDatabaseName() {
// TODO Auto-generated method stub
return null;
}
}
在 application.properties 文件中禁用自动索引创建
spring.data.mongodb.auto-index-creation=false
或application.yml文件
spring:
data:
mongodb:
auto-index-creation: false
创建带有@Configuration 注释的class MongoConfiguration
Injetc 这个依赖项
private final MongoTemplate mongoTemplate;
private final MongoConverter mongoConverter;
并添加此方法
@EventListener(ApplicationReadyEvent.class)
public void initIndicesAfterStartup() {
log.info("Mongo InitIndicesAfterStartup init");
var init = System.currentTimeMillis();
var mappingContext = this.mongoConverter.getMappingContext();
if (mappingContext instanceof MongoMappingContext) {
MongoMappingContext mongoMappingContext = (MongoMappingContext) mappingContext;
for (BasicMongoPersistentEntity<?> persistentEntity : mongoMappingContext.getPersistentEntities()) {
var clazz = persistentEntity.getType();
if (clazz.isAnnotationPresent(Document.class)) {
var resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);
var indexOps = mongoTemplate.indexOps(clazz);
resolver.resolveIndexFor(clazz).forEach(indexOps::ensureIndex);
}
}
}
log.info("Mongo InitIndicesAfterStartup take: {}", (System.currentTimeMillis() - init));
}
记住 var 只适用于 java 11+
最终的class,它使用了Lombok
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexResolver;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
@Slf4j
@RequiredArgsConstructor
@Configuration
public class MongoConfiguration {
private final MongoTemplate mongoTemplate;
private final MongoConverter mongoConverter;
@EventListener(ApplicationReadyEvent.class)
public void initIndicesAfterStartup() {
log.info("Mongo InitIndicesAfterStartup init");
var init = System.currentTimeMillis();
var mappingContext = this.mongoConverter.getMappingContext();
if (mappingContext instanceof MongoMappingContext) {
MongoMappingContext mongoMappingContext = (MongoMappingContext) mappingContext;
for (BasicMongoPersistentEntity<?> persistentEntity : mongoMappingContext.getPersistentEntities()) {
var clazz = persistentEntity.getType();
if (clazz.isAnnotationPresent(Document.class)) {
var resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);
var indexOps = mongoTemplate.indexOps(clazz);
resolver.resolveIndexFor(clazz).forEach(indexOps::ensureIndex);
}
}
}
log.info("Mongo InitIndicesAfterStartup take: {}", (System.currentTimeMillis() - init));
}
}
但该解决方案效果不佳,至少在反应式上下文中是这样。此时 mongoMappingContext.getPersistentEntities()
为空。只有auto-index-creation: true
(甚至mongoMappingContext.setAutoIndexCreation(true)
)才能保证索引的创建。
尝试了以下配置,我什至创建了一个自己的 mappingContext bean
@Configuration
public class MongoConfiguration extends AbstractMongoClientConfiguration {
private final AbstractCloudConfig abstractCloudConfig;
@Autowired
public MongoConfiguration(AbstractCloudConfig abstractCloudConfig) {
this.abstractCloudConfig = abstractCloudConfig;
}
@Override
public MongoClient mongoClient() {
return MongoClients.create(MongoClientSettings.builder().build());
}
@Bean
@Override
public MongoDbFactory mongoDbFactory() {
return abstractCloudConfig.connectionFactory().mongoDbFactory();
}
@Bean
public MappingMongoConverter mongoConverter(MappingMongoConverter mongoConverter) {
/*
* For some obscure reason, Spring Mongo does not like hash maps with keys that contain dots '.'.
* We configure to replace dots '.' in maps with some obscure character that does not occur in in keys.
*/
mongoConverter.setMapKeyDotReplacement("~");
return mongoConverter;
}
@Bean
public MongoMappingContext mongoMappingContext() throws ClassNotFoundException {
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(this.getInitialEntitySet());
mappingContext.setSimpleTypeHolder(this.customConversions().getSimpleTypeHolder());
mappingContext.setFieldNamingStrategy(this.fieldNamingStrategy());
mappingContext.setAutoIndexCreation(false);
return mappingContext;
}
@Override
protected String getDatabaseName() {
throw new RuntimeException("This method should not be called");
}
@EventListener(ApplicationReadyEvent.class)
public void initIndicesAfterStartup() throws ClassNotFoundException {
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
this.mongoMappingContext().setAutoIndexCreation(false);
createIndexForEntity(DataSetDefinitionV2.class, mongoTemplate);
createIndexForEntity(ModelConfiguration.class, mongoTemplate);
createIndexForEntity(ScheduleEntity.class, mongoTemplate);
}
private void createIndexForEntity(Class<?> entityClass, MongoTemplate mongoTemplate) throws ClassNotFoundException {
IndexOperations indexOps = mongoTemplate.indexOps(entityClass);
IndexResolver resolver = new MongoPersistentEntityIndexResolver(this.mongoMappingContext());
resolver.resolveIndexFor(entityClass).forEach(indexOps::ensureIndex);
}
}
仍然是警告 comes.I 事件在 application.properties 中尝试了 spring.data.mongodb.auto-index-creation=false,也没有成功
除了 Juan Ibarra 评论外,将此添加到 application.yml 文件对我不起作用:
spring:
data:
mongodb:
auto-index-creation: false
但在 AbstractMongoClientConfiguration 中覆盖 autoIndexCreation() 有效:
@Override
protected boolean autoIndexCreation() {
return false;
}