Skip to content

Commit 5a04711

Browse files
authored
DefaultCouchbaseTypeMapper uses TypeAlias annotation if present.
DefaultCouchbaseTypeMapper uses TypeAlias annotation if present. Test case also uncovered that TypeAlias was being ignored for string queries. Closes #1119. Original pull request: #1120. Co-authored-by: mikereiche <michael.reiche@couchbase.com>
1 parent 9b848f6 commit 5a04711

File tree

5 files changed

+79
-5
lines changed

5 files changed

+79
-5
lines changed

src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2021 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,17 +16,21 @@
1616

1717
package org.springframework.data.couchbase.core.convert;
1818

19+
import java.util.Collections;
20+
1921
import org.springframework.data.convert.DefaultTypeMapper;
2022
import org.springframework.data.convert.TypeAliasAccessor;
2123
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
2224
import org.springframework.data.mapping.Alias;
25+
import org.springframework.data.mapping.context.MappingContext;
2326
import org.springframework.data.util.TypeInformation;
2427

2528
/**
2629
* The Couchbase Type Mapper.
2730
*
2831
* @author Michael Nitschinger
2932
* @author Mark Paluch
33+
* @author Michael Reiche
3034
*/
3135
public class DefaultCouchbaseTypeMapper extends DefaultTypeMapper<CouchbaseDocument> implements CouchbaseTypeMapper {
3236

@@ -43,7 +47,8 @@ public class DefaultCouchbaseTypeMapper extends DefaultTypeMapper<CouchbaseDocum
4347
* @param typeKey the typeKey to use.
4448
*/
4549
public DefaultCouchbaseTypeMapper(final String typeKey) {
46-
super(new CouchbaseDocumentTypeAliasAccessor(typeKey));
50+
super(new CouchbaseDocumentTypeAliasAccessor(typeKey), (MappingContext) null,
51+
Collections.singletonList(new TypeAwareTypeInformationMapper()));
4752
this.typeKey = typeKey;
4853
}
4954

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2012-2021 the original author or authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.couchbase.core.convert;
17+
18+
import org.springframework.data.annotation.TypeAlias;
19+
import org.springframework.data.convert.SimpleTypeInformationMapper;
20+
import org.springframework.data.mapping.Alias;
21+
import org.springframework.data.util.TypeInformation;
22+
23+
/**
24+
* TypeAwareTypeInformationMapper - leverages @TypeAlias
25+
*
26+
* @author Michael Reiche
27+
*/
28+
public class TypeAwareTypeInformationMapper extends SimpleTypeInformationMapper {
29+
30+
@Override
31+
public Alias createAliasFor(TypeInformation<?> type) {
32+
TypeAlias[] typeAlias = type.getType().getAnnotationsByType(TypeAlias.class);
33+
34+
if (typeAlias.length == 1) {
35+
return Alias.of(typeAlias[0].value());
36+
}
37+
38+
return super.createAliasFor(type);
39+
}
40+
}

src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.data.couchbase.core.query.QueryCriteria;
2828
import org.springframework.data.couchbase.core.query.StringQuery;
2929
import org.springframework.data.domain.Sort;
30+
import org.springframework.data.mapping.Alias;
3031
import org.springframework.data.mapping.PersistentPropertyPath;
3132
import org.springframework.data.mapping.context.MappingContext;
3233
import org.springframework.data.repository.core.NamedQueries;
@@ -36,6 +37,8 @@
3637
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
3738
import org.springframework.data.repository.query.parser.Part;
3839
import org.springframework.data.repository.query.parser.PartTree;
40+
import org.springframework.data.util.ClassTypeInformation;
41+
import org.springframework.data.util.TypeInformation;
3942
import org.springframework.expression.spel.standard.SpelExpressionParser;
4043

4144
import com.couchbase.client.java.json.JsonArray;
@@ -81,8 +84,15 @@ public StringN1qlQueryCreator(final ParameterAccessor accessor, CouchbaseQueryMe
8184
} else {
8285
throw new IllegalArgumentException("query has no inline Query or named Query not found");
8386
}
87+
Class javaType = getType();
88+
String typeValue = javaType.getName();
89+
TypeInformation<?> typeInfo = ClassTypeInformation.from(javaType);
90+
Alias alias = couchbaseConverter.getTypeAlias(typeInfo);
91+
if (alias != null && alias.isPresent()) {
92+
typeValue = alias.toString();
93+
}
8494
this.queryParser = new StringBasedN1qlQueryParser(queryString, queryMethod, bucketName, couchbaseConverter,
85-
getTypeField(), getTypeValue(), accessor, spelExpressionParser, evaluationContextProvider);
95+
getTypeField(), typeValue, accessor, spelExpressionParser, evaluationContextProvider);
8696
this.parser = spelExpressionParser;
8797
this.parsedExpression = this.queryParser.parsedExpression;
8898
}
@@ -95,8 +105,8 @@ protected String getTypeField() {
95105
return couchbaseConverter.getTypeKey();
96106
}
97107

98-
protected String getTypeValue() {
99-
return getQueryMethod().getEntityInformation().getJavaType().getName();
108+
protected Class getType() {
109+
return getQueryMethod().getEntityInformation().getJavaType();
100110
}
101111

102112
@Override

src/test/java/org/springframework/data/couchbase/domain/Airport.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.springframework.data.annotation.Id;
2020
import org.springframework.data.annotation.PersistenceConstructor;
21+
import org.springframework.data.annotation.TypeAlias;
2122
import org.springframework.data.couchbase.core.mapping.Document;
2223

2324
/**
@@ -27,6 +28,7 @@
2728
* @author Michael Reiche
2829
*/
2930
@Document
31+
@TypeAlias("airport")
3032
public class Airport extends ComparableEntity {
3133
@Id String id;
3234

src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import org.springframework.data.couchbase.CouchbaseClientFactory;
4444
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
4545
import org.springframework.data.couchbase.core.CouchbaseTemplate;
46+
import org.springframework.data.couchbase.core.query.N1QLExpression;
47+
import org.springframework.data.couchbase.core.query.Query;
4648
import org.springframework.data.couchbase.core.query.QueryCriteria;
4749
import org.springframework.data.couchbase.domain.Address;
4850
import org.springframework.data.couchbase.domain.Airport;
@@ -170,6 +172,20 @@ void findBySimpleProperty() {
170172
}
171173
}
172174

175+
@Test
176+
void findByTypeAlias() {
177+
Airport vie = null;
178+
try {
179+
vie = new Airport("airports::vie", "vie", "loww");
180+
vie = airportRepository.save(vie);
181+
List<Airport> airports = couchbaseTemplate.findByQuery(Airport.class)
182+
.matching(new Query(QueryCriteria.where(N1QLExpression.x("_class")).is("airport"))).all();
183+
assertFalse(airports.isEmpty(), "should have found aiport");
184+
} finally {
185+
airportRepository.delete(vie);
186+
}
187+
}
188+
173189
@Test
174190
void findByEnum() {
175191
Airport vie = null;
@@ -204,6 +220,7 @@ void count() {
204220
airportRepository.saveAll(
205221
Arrays.stream(iatas).map((iata) -> new Airport("airports::" + iata, iata, iata.toLowerCase(Locale.ROOT)))
206222
.collect(Collectors.toSet()));
223+
couchbaseTemplate.findByQuery(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
207224
Long count = airportRepository.countFancyExpression(asList("JFK"), asList("jfk"), false);
208225
assertEquals(1, count);
209226

0 commit comments

Comments
 (0)