diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java b/src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java index 3600044ed..91749a83b 100644 --- a/src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java +++ b/src/main/java/org/springframework/data/couchbase/core/convert/DefaultCouchbaseTypeMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors + * Copyright 2012-2021 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. @@ -16,10 +16,13 @@ package org.springframework.data.couchbase.core.convert; +import java.util.Collections; + import org.springframework.data.convert.DefaultTypeMapper; import org.springframework.data.convert.TypeAliasAccessor; import org.springframework.data.couchbase.core.mapping.CouchbaseDocument; import org.springframework.data.mapping.Alias; +import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.util.TypeInformation; /** @@ -27,6 +30,7 @@ * * @author Michael Nitschinger * @author Mark Paluch + * @author Michael Reiche */ public class DefaultCouchbaseTypeMapper extends DefaultTypeMapper implements CouchbaseTypeMapper { @@ -43,7 +47,8 @@ public class DefaultCouchbaseTypeMapper extends DefaultTypeMapper type) { + TypeAlias[] typeAlias = type.getType().getAnnotationsByType(TypeAlias.class); + + if (typeAlias.length == 1) { + return Alias.of(typeAlias[0].value()); + } + + return super.createAliasFor(type); + } +} diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java b/src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java index 1e7d8e29a..65f389966 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java @@ -27,6 +27,7 @@ import org.springframework.data.couchbase.core.query.QueryCriteria; import org.springframework.data.couchbase.core.query.StringQuery; import org.springframework.data.domain.Sort; +import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.repository.core.NamedQueries; @@ -36,6 +37,8 @@ import org.springframework.data.repository.query.parser.AbstractQueryCreator; import org.springframework.data.repository.query.parser.Part; import org.springframework.data.repository.query.parser.PartTree; +import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.TypeInformation; import org.springframework.expression.spel.standard.SpelExpressionParser; import com.couchbase.client.java.json.JsonArray; @@ -81,8 +84,15 @@ public StringN1qlQueryCreator(final ParameterAccessor accessor, CouchbaseQueryMe } else { throw new IllegalArgumentException("query has no inline Query or named Query not found"); } + Class javaType = getType(); + String typeValue = javaType.getName(); + TypeInformation typeInfo = ClassTypeInformation.from(javaType); + Alias alias = couchbaseConverter.getTypeAlias(typeInfo); + if (alias != null && alias.isPresent()) { + typeValue = alias.toString(); + } this.queryParser = new StringBasedN1qlQueryParser(queryString, queryMethod, bucketName, couchbaseConverter, - getTypeField(), getTypeValue(), accessor, spelExpressionParser, evaluationContextProvider); + getTypeField(), typeValue, accessor, spelExpressionParser, evaluationContextProvider); this.parser = spelExpressionParser; this.parsedExpression = this.queryParser.parsedExpression; } @@ -95,8 +105,8 @@ protected String getTypeField() { return couchbaseConverter.getTypeKey(); } - protected String getTypeValue() { - return getQueryMethod().getEntityInformation().getJavaType().getName(); + protected Class getType() { + return getQueryMethod().getEntityInformation().getJavaType(); } @Override diff --git a/src/test/java/org/springframework/data/couchbase/domain/Airport.java b/src/test/java/org/springframework/data/couchbase/domain/Airport.java index d6208eeeb..eb0441894 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/Airport.java +++ b/src/test/java/org/springframework/data/couchbase/domain/Airport.java @@ -18,6 +18,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.TypeAlias; import org.springframework.data.couchbase.core.mapping.Document; /** @@ -27,6 +28,7 @@ * @author Michael Reiche */ @Document +@TypeAlias("airport") public class Airport extends ComparableEntity { @Id String id; diff --git a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java index f0d17add4..eab69030d 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java @@ -34,7 +34,6 @@ import java.util.concurrent.Future; import java.util.stream.Collectors; -import com.couchbase.client.java.query.QueryScanConsistency; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -43,6 +42,8 @@ import org.springframework.data.couchbase.CouchbaseClientFactory; import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; import org.springframework.data.couchbase.core.CouchbaseTemplate; +import org.springframework.data.couchbase.core.query.N1QLExpression; +import org.springframework.data.couchbase.core.query.Query; import org.springframework.data.couchbase.core.query.QueryCriteria; import org.springframework.data.couchbase.domain.Address; import org.springframework.data.couchbase.domain.Airport; @@ -67,6 +68,7 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import com.couchbase.client.core.error.IndexExistsException; +import com.couchbase.client.java.query.QueryScanConsistency; /** * Repository tests @@ -168,6 +170,20 @@ void findBySimpleProperty() { } } + @Test + void findByTypeAlias() { + Airport vie = null; + try { + vie = new Airport("airports::vie", "vie", "loww"); + vie = airportRepository.save(vie); + List airports = couchbaseTemplate.findByQuery(Airport.class) + .matching(new Query(QueryCriteria.where(N1QLExpression.x("_class")).is("airport"))).all(); + assertFalse(airports.isEmpty(), "should have found aiport"); + } finally { + airportRepository.delete(vie); + } + } + @Test void findByEnum() { Airport vie = null; @@ -180,6 +196,7 @@ void findByEnum() { airportRepository.delete(vie); } } + @Test public void testCas() { User user = new User("1", "Dave", "Wilson"); @@ -200,6 +217,7 @@ void count() { airportRepository.saveAll( Arrays.stream(iatas).map((iata) -> new Airport("airports::" + iata, iata, iata.toLowerCase(Locale.ROOT))) .collect(Collectors.toSet())); + couchbaseTemplate.findByQuery(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all(); Long count = airportRepository.countFancyExpression(asList("JFK"), asList("jfk"), false); assertEquals(1, count); @@ -332,14 +350,15 @@ void deleteAllById() { void couchbaseRepositoryQuery() throws Exception { User user = new User("1", "Dave", "Wilson"); userRepository.save(user); - couchbaseTemplate.findByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).matching(QueryCriteria.where("firstname").is("Dave").and("`1`").is("`1`")).all(); + couchbaseTemplate.findByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS) + .matching(QueryCriteria.where("firstname").is("Dave").and("`1`").is("`1`")).all(); String input = "findByFirstname"; Method method = UserRepository.class.getMethod(input, String.class); CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(), couchbaseTemplate.getConverter().getMappingContext()); CouchbaseRepositoryQuery query = new CouchbaseRepositoryQuery(couchbaseTemplate, queryMethod, null); - List users = (List)query.execute(new String[] { "Dave" }); + List users = (List) query.execute(new String[] { "Dave" }); assertEquals(user, users.get(0)); }