【问题标题】:Spring Data MongoDB Repository with custom collection name具有自定义集合名称的 Spring Data MongoDB 存储库
【发布时间】:2015-06-18 07:12:46
【问题描述】:

我正在使用 Spring Data for MongoDB,我需要能够在运行时配置集合。

我的仓库定义为:

@Repository
public interface EventDataRepository extends MongoRepository<EventData, String> {
}

我尝试了这个愚蠢的例子:

@Document(collection = "${mongo.event.collection}")
public class EventData implements Serializable {

但 mongo.event.collection 并没有像使用 @Value 注释那样解析为名称。

更多的调试和搜索,我尝试了以下方法: @Document(collection = "#{${mongo.event.collection}}")

这产生了一个异常:

Caused by: org.springframework.expression.spel.SpelParseException: EL1041E:(pos 1): After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
    at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:129)
    at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:60)
    at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:32)
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpressions(TemplateAwareExpressionParser.java:154)
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseTemplate(TemplateAwareExpressionParser.java:85)

也许我只是不知道如何完全使用 SPel 来访问 Spring 的属性配置器中的值。

在单步执行代码时,我看到有一种方法可以指定集合名称甚至表达式,但是,我不确定应该为此目的使用哪个注释或如何做到这一点。

谢谢。 -AP_

【问题讨论】:

  • 也许这是你的问题? jira.spring.io/browse/DATAMONGO-1043...你用的是哪个版本的spring-data-mongodb?
  • 可能是(我使用的是 1.7.0-RELEASE),但是,您提到的问题涉及多个调用之间的查询中的表达式。但是,您确实提示我它必须是正确的 SPEL 表达式,所以我更改了它。查看更新的问题。

标签: java spring mongodb repository


【解决方案1】:

所以,最后,这里有一个解决方法。我想我真的不知道如何使用 SPeL 表达式从 Spring Properties Configurationr 访问数据。

在我的@Configuration 类中:

@Value("${mongo.event.collection}")
private String
    mongoEventCollectionName;

@Bean
public String mongoEventCollectionName() {
    return
        mongoEventCollectionName;
}

在我的文档上:

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

这似乎可以正常工作并正确获取我的 .properties 文件中配置的名称,但是,我仍然不确定为什么我不能像在 @Value 注释中那样使用 $ 访问值。

【讨论】:

  • 这个答案在某些方面帮助了我,但我不断收到错误消息“在 null 上找不到属性或字段 'mongoEventCollectionName'”。注入 bean 似乎工作正常,但不是注入 @Document
  • 感谢this answer,我得到了它的工作:将 ApplicationContext 设置为 MongoMappingContext。
【解决方案2】:

您只需使用 SPeL 即可解决此问题:

@Document(collection = "#{environment.getProperty('mongo.event.collection')}")
public class EventData implements Serializable {
    ...
}

更新 Spring 5.x:

从 Spring 5.x 左右开始,环境之前需要一个额外的@:

@Document(collection = "#{@environment.getProperty('mongo.event.collection')}")
public class EventData implements Serializable {
    ...
}

文档:

【讨论】:

  • 你是一个救生员。我知道cmets不应该用来谢谢。但这回答了我的很多问题。您能否提供来自 Spring 文档的参考资料。
  • 我添加了一些文档来描述示例代码中使用的所有部分。这对你有帮助吗?
  • 对于那些在 Spring Docs 中无法使用章节链接的人。参考第四章
  • 我在 href 标签中添加了章节编号。
【解决方案3】:

定义你的实体类

@Document(collection = "${EventDataRepository.getCollectionName()}")
public class EventData implements Serializable {

使用“collectionName”的 getter 和 setter 方法定义自定义存储库接口

public interface EventDataRepositoryCustom {

    String getCollectionName();

    void setCollectionName(String collectionName);
}

通过“collectionName”实现为自定义存储库提供实现类

public class EventDataRepositoryImpl implements EventDataRepositoryCustom{

    private static String collectionName = "myCollection";

    @Override
    public String getCollectionName() {
        return collectionName;
    }

    @Override
    public void setCollectionName(String collectionName) {
        this.collectionName = collectionName;
    }
}

EventDataRepositoryImpl 添加到存储库接口的扩展列表中,如下所示

@Repository
public interface EventDataRepository extends MongoRepository<EventData, String>, EventDataRepositoryImpl  {
}

现在在您使用 MongoRepository 的服务类中设置集合名称,它看起来像

@Autowired
EventDataRepository  repository ;

repository.setCollectionName("collectionName");

【讨论】:

    【解决方案4】:

    实体类

    @Document    // remove the parameters from here
    
    
    public class EscalationCase 
    {
    
    }
    

    配置类

    public class MongoDBConfiguration {
    
        private final Logger logger = LoggerFactory.getLogger(MongoDBConfiguration.class);
    
        @Value("${sfdc.mongodb.collection}") //taking collection name from properties file 
        private String collectionName;
    
        @Bean
    
        public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext context) {
    
            MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory), context);
            converter.setTypeMapper(new DefaultMongoTypeMapper(null));
            MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);
            if (!mongoTemplate.collectionExists(collectionName)) {
                mongoTemplate.createCollection(collectionName);  // adding the collection name here
            }
            return mongoTemplate;
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-06
      • 2017-02-09
      • 2018-10-06
      • 2017-09-19
      • 2016-08-29
      • 1970-01-01
      • 2018-04-02
      • 2015-07-10
      • 2020-11-23
      相关资源
      最近更新 更多