From 5a78ba31f40c6b85e3f4a16a3487f57b6cde86f9 Mon Sep 17 00:00:00 2001 From: Mohsin Husen Date: Sun, 23 Mar 2014 19:06:47 +0000 Subject: [PATCH] DATAES-73 - NullPointerException while persist a Map as part of persistent entity --- .../SimpleElasticsearchPersistentEntity.java | 18 +++--- ...SimpleElasticsearchPersistentProperty.java | 2 +- .../data/elasticsearch/InnerObjectTests.java | 1 + .../data/elasticsearch/NestedObjectTests.java | 58 +++++++++++++++++-- .../data/elasticsearch/entities/Book.java | 14 +++++ 5 files changed, 80 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index a76ff9b52..995bf7d87 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,13 +119,15 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit public void addPersistentProperty(ElasticsearchPersistentProperty property) { super.addPersistentProperty(property); - Parent parent = property.getField().getAnnotation(Parent.class); - if (parent != null) { - Assert.isNull(this.parentIdProperty, "Only one field can hold a @Parent annotation"); - Assert.isNull(this.parentType, "Only one field can hold a @Parent annotation"); - Assert.isTrue(property.getType() == String.class, "Parent ID property should be String"); - this.parentIdProperty = property; - this.parentType = parent.type(); + if (property.getField() != null) { + Parent parent = property.getField().getAnnotation(Parent.class); + if (parent != null) { + Assert.isNull(this.parentIdProperty, "Only one field can hold a @Parent annotation"); + Assert.isNull(this.parentType, "Only one field can hold a @Parent annotation"); + Assert.isTrue(property.getType() == String.class, "Parent ID property should be String"); + this.parentIdProperty = property; + this.parentType = parent.type(); + } } if (property.isVersionProperty()) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index fc48bdbcd..ca80d0817 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -55,7 +55,7 @@ public class SimpleElasticsearchPersistentProperty extends @Override public boolean isIdProperty() { - return super.isIdProperty() || SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName()); + return super.isIdProperty() || field != null ? SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName()) : false; } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/InnerObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/InnerObjectTests.java index 51c498632..8ff569db2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/InnerObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/InnerObjectTests.java @@ -49,6 +49,7 @@ public class InnerObjectTests { public void before() { elasticsearchTemplate.deleteIndex(Book.class); elasticsearchTemplate.createIndex(Book.class); + elasticsearchTemplate.putMapping(Book.class); elasticsearchTemplate.refresh(Book.class, true); } diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 6fd5b7cff..a8b9900f1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -15,13 +15,13 @@ */ package org.springframework.data.elasticsearch; +import static org.apache.commons.lang.RandomStringUtils.*; import static org.elasticsearch.index.query.QueryBuilders.*; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; @@ -56,6 +56,7 @@ public class NestedObjectTests { public void before() { elasticsearchTemplate.deleteIndex(Book.class); elasticsearchTemplate.createIndex(Book.class); + elasticsearchTemplate.putMapping(Book.class); elasticsearchTemplate.refresh(Book.class, true); elasticsearchTemplate.deleteIndex(Person.class); elasticsearchTemplate.createIndex(Person.class); @@ -301,4 +302,53 @@ public class NestedObjectTests { assertThat(persons.size(), is(1)); } + + /* + DATAES-73 + */ + @Test + public void shouldIndexAndSearchMapAsNestedType() { + //given + Book book1 = new Book(); + Book book2 = new Book(); + + book1.setId(randomNumeric(5)); + book1.setName("testBook1"); + + book2.setId(randomNumeric(5)); + book2.setName("testBook2"); + + Map> map1 = new HashMap>(); + map1.put(1, Arrays.asList("test1", "test2")); + + Map> map2 = new HashMap>(); + map2.put(1, Arrays.asList("test3", "test4")); + + book1.setBuckets(map1); + book2.setBuckets(map2); + + List indexQueries = new ArrayList(); + IndexQuery indexQuery1 = new IndexQuery(); + indexQuery1.setId(book1.getId()); + indexQuery1.setObject(book1); + + IndexQuery indexQuery2 = new IndexQuery(); + indexQuery2.setId(book2.getId()); + indexQuery2.setObject(book2); + + indexQueries.add(indexQuery1); + indexQueries.add(indexQuery2); + //when + elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.refresh(Book.class, true); + //then + SearchQuery searchQuery = new NativeSearchQueryBuilder() + .withQuery(nestedQuery("buckets", termQuery("buckets.1", "test3"))) + .build(); + Page books = elasticsearchTemplate.queryForPage(searchQuery, Book.class); + + assertThat(books.getContent().size(), is(1)); + assertThat(books.getContent().get(0).getId(), is(book2.getId())); + } } + diff --git a/src/test/java/org/springframework/data/elasticsearch/entities/Book.java b/src/test/java/org/springframework/data/elasticsearch/entities/Book.java index a3297d95e..cc433beee 100644 --- a/src/test/java/org/springframework/data/elasticsearch/entities/Book.java +++ b/src/test/java/org/springframework/data/elasticsearch/entities/Book.java @@ -15,6 +15,10 @@ */ package org.springframework.data.elasticsearch.entities; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; @@ -32,6 +36,8 @@ public class Book { private String name; @Field(type = FieldType.Object) private Author author; + @Field(type = FieldType.Nested) + private Map> buckets = new HashMap>(); public String getId() { return id; @@ -56,4 +62,12 @@ public class Book { public void setAuthor(Author author) { this.author = author; } + + public Map> getBuckets() { + return buckets; + } + + public void setBuckets(Map> buckets) { + this.buckets = buckets; + } }