无法在SpEL中为Spring Data MongoDB集合名称解析bean

时间:2017-01-17 13:29:14

标签: spring-boot spring-batch spring-data-mongodb spring-el

我正在尝试使用Spring Data MongoDB和Spring Batch自定义保存实体类并将其编入索引的集合名称。该类声明如下:

@Document
@CompoundIndex(name = "unique_source", def = "{'fid': 1, 'sid': 1}", unique = true, background = true)
public class VariantSource {
    ...
}

项目作者:

public class VariantSourceMongoWriter extends MongoItemWriter<VariantSource> {

    public VariantSourceEntityMongoWriter(MongoOperations mongoOperations, String collectionName) {
        setTemplate(mongoOperations);
        setCollection(collectionName);
    }
}

保存工作正常:将对象写入作为参数提供的集合中。问题是索引是在默认集合中创建的,以类名(variantSource)命名。

在阅读thisthis后,我创建了以下内容:

public class MongoCollections {

    public String getCollectionFilesName() {
        return "my_custom_collection_name"; // TODO Dynamic value
    }
}


@Configuration
public class MongoCollectionsConfiguration {

    @Bean
    public MongoCollections mongoCollections() {
        return new MongoCollections(); 
    }


@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {MongoCollectionsConfiguration.class})
public class VariantSourceMongoWriterTest {

    @Autowired
    private MongoCollections mongoCollections;

}

我已经检查过实例已正确自动连接到单元测试中,但我无法使其与SpEL一起使用。

@Document注释更改为如下所示:

@Document(collection = "#{@mongoCollections.getCollectionFilesName()}")

抛出以下异常:

  

org.springframework.expression.spel.SpelEvaluationException:EL1057E:(pos 1):在上下文中没有注册bean解析器来解析对'mongoCollections'的访问权限

如果我使用它:

@Document(collection = "#{mongoCollections.getCollectionFilesName()}")

例外是这个:

  

org.springframework.expression.spel.SpelEvaluationException:EL1007E:(pos 0):在null上找不到属性或字段'mongoCollections'

最后,下面创建一个名称为指定的集合,包括符号:

@Document(collection = "@mongoCollections.getCollectionFilesName()")

3 个答案:

答案 0 :(得分:1)

正如this answer指出的那样,修复注射:

// Declaring a variable with let causes the variable to have "block-level"
// scope. In this case the block is the loop's contents and for each iteration of the
// loop. Upon each iteration, a new "x" will be created, so a different scope from 
// the old "x" is what's used.
for (let x = 0; x < 5; x++) {
    var timeoutFunction = function() {
        return function() {
            console.log(x)
        }
    }
    setTimeout(timeoutFunction(), 1)
}
  

SpelEvaluationException:EL1007E:(pos 0):在null上找不到属性或字段'mongoCollections'

(或直接方法bean:@Document(collection = "#{mongoCollections.getCollectionFilesName()}") ),尝试将ApplicationContext设置为MongoMappingContext(用于实例化MongoConverter,以及稍后的MongoTemplate):

@Document(collection = "#{getCollectionFilesName}")

答案 1 :(得分:0)

确保您的bean mongoCollections已在应用程序上下文中注册, 并按以下方式更正SpEL表达式。

@Document(collection =“#{@ mongoCollections.getCollectionFilesName()}”)

答案 2 :(得分:0)

只需更改我的 @Document 配置文件,我就能让我的 MongoTemplate 标记访问 bean。

以前,我是这样设置的:

@Configuration
public class MongoTemplateConfiguration {

    ...

    @Bean
    public MongoTemplate mongoTemplate() {
        ...
        return new MongoTemplate(...);
    }
}

将其更改为遵循 this (3.2 Java Configuration) 格式是我所需要的,以消除“bean 解析器”错误:

@Configuration
public class MongoTemplateConfiguration extends AbstractMongoClientConfiguration {

    ...

    @Override
    @Bean
    public com.mongodb.client.MongoClient mongoClient() {
        MongoClientSettings settings = ...;
        return MongoClients.create(settings);
    }
}