агрегация spring-data-mongodb с составным идентификатором - PullRequest
0 голосов
/ 16 мая 2018

У меня проблемы с чтением документов из MongoDB с использованием структуры агрегации: я всегда получаю нулевые идентификаторы в моих результатах. Это происходит только для документов, которые имеют составные идентификаторы. Я пробовал разные версии spring-data-mongodb (1.10.12, 2.0.7), тот же результат.

Класс определения сущности

    @Document(collection="entities")
    public class MyEntity {
    static class CompositeKey implements Serializable {
        private String stringKey;

        private Integer intKey;

        public CompositeKey(String stringKey, Integer intKey) {
            this.stringKey = stringKey;
            this.intKey = intKey;
        }

        public Integer getIntKey() {
            return intKey;
        }

        public String getStringKey() {
            return stringKey;
        }

        public String toString() {
            return "{" + stringKey + " - " + intKey + "}";
        }
    }

    @Id
    private CompositeKey id;

    private String param;

    public MyEntity() {}

    public MyEntity(String stringKey, Integer intKey) {
        id = new CompositeKey(stringKey, intKey);
    }

    public CompositeKey getId(){
        return id;
    }

    public void setId(CompositeKey id) {
        this.id = id;
    }

    public String getParam() {
        return param;
    }

    public void setParam(String param) {
        this.param = param;
    }
}

Тестовый код

public static void main(String[] args) {        
    MongoClient client = new MongoClient("127.0.0.1");
    SimpleMongoDbFactory factory = new SimpleMongoDbFactory(client, "aggTest");
    MongoTemplate mongoTemplate = new MongoTemplate(factory);

    MyEntity entity = new MyEntity();
    entity.setId(new MyEntity.CompositeKey("one", 1));
    entity.setParam("param1");
    mongoTemplate.save(entity);

    entity = new MyEntity();
    entity.setId(new MyEntity.CompositeKey("two", 2));
    entity.setParam("param2");
    mongoTemplate.save(entity);

    Criteria crit = Criteria.where("param").ne("param3");
    List<AggregationOperation> aggOpList = new ArrayList<AggregationOperation>();
    aggOpList.add(Aggregation.match(crit));

    System.out.println("Documents fetched with find: ");        
    for (MyEntity aggResult : mongoTemplate.find(new Query(crit), MyEntity.class).toArray(new MyEntity[0]))
        System.out.println(aggResult.getId() + " - " + aggResult.getParam());

    System.out.println("\nDocuments fetched with aggregate: ");        
    TypedAggregation<MyEntity> aggregation = new TypedAggregation<>(MyEntity.class, aggOpList);
    AggregationResults<MyEntity> aggregate = mongoTemplate.aggregate(aggregation, MyEntity.class);      
    for (MyEntity aggResult : aggregate.getMappedResults())
        System.out.println(aggResult.getId() + " - " + aggResult.getParam());       
}

выход

Documents fetched with find: 
{one - 1} - param1
{two - 2} - param2

Documents fetched with aggregate: 
null - param1
null - param2

Отладка в следующем методе MappingMongoConverter.read (конечная сущность MongoPersistentEntity, конечный документ bson, конечный путь ObjectPath) Я обнаружил, что в первом случае (метод find) переменная documentAccessor имеет следующее содержимое

Document {{_ id = Document {{stringKey = one, intKey = 1}}, param = param1, _class = MyEntity}}

тогда как во втором случае (запрос агрегации) это выглядит как

Document {{stringKey = one, intKey = 1, param = param1, _class = MyEntity}}

Документ каким-то образом выравнивается, что делает невозможным для преобразователя заполнение поля идентификатора. Должно быть, я что-то делаю не так, но что?

...