11/*
2- * Copyright 2019-2021 the original author or authors.
2+ * Copyright 2019-2022 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.
1616package org .springframework .data .jdbc .repository ;
1717
1818import static java .util .Arrays .*;
19+ import static java .util .Collections .*;
1920import static org .assertj .core .api .Assertions .*;
2021import static org .assertj .core .api .SoftAssertions .*;
2122import static org .springframework .test .context .TestExecutionListeners .MergeMode .*;
2223
2324import java .math .BigDecimal ;
2425import java .sql .JDBCType ;
2526import java .util .Date ;
27+ import java .util .List ;
2628
2729import org .junit .jupiter .api .Test ;
2830import org .junit .jupiter .api .extension .ExtendWith ;
3638import org .springframework .data .convert .WritingConverter ;
3739import org .springframework .data .jdbc .core .convert .JdbcCustomConversions ;
3840import org .springframework .data .jdbc .core .convert .JdbcValue ;
41+ import org .springframework .data .jdbc .repository .query .Query ;
3942import org .springframework .data .jdbc .repository .support .JdbcRepositoryFactory ;
4043import org .springframework .data .jdbc .testing .AssumeFeatureTestExecutionListener ;
4144import org .springframework .data .jdbc .testing .TestConfiguration ;
5053 *
5154 * @author Jens Schauder
5255 * @author Sanghyuk Jung
56+ * @author Chirag Tailor
5357 */
5458@ ContextConfiguration
5559@ Transactional
@@ -69,18 +73,19 @@ Class<?> testClass() {
6973 }
7074
7175 @ Bean
72- EntityWithBooleanRepository repository () {
73- return factory .getRepository (EntityWithBooleanRepository .class );
76+ EntityWithStringyBigDecimalRepository repository () {
77+ return factory .getRepository (EntityWithStringyBigDecimalRepository .class );
7478 }
7579
7680 @ Bean
7781 JdbcCustomConversions jdbcCustomConversions () {
7882 return new JdbcCustomConversions (asList (StringToBigDecimalConverter .INSTANCE , BigDecimalToString .INSTANCE ,
79- CustomIdReadingConverter .INSTANCE , CustomIdWritingConverter .INSTANCE ));
83+ CustomIdReadingConverter .INSTANCE , CustomIdWritingConverter .INSTANCE , DirectionToIntegerConverter .INSTANCE ,
84+ NumberToDirectionConverter .INSTANCE , IntegerToDirectionConverter .INSTANCE ));
8085 }
8186 }
8287
83- @ Autowired EntityWithBooleanRepository repository ;
88+ @ Autowired EntityWithStringyBigDecimalRepository repository ;
8489
8590 /**
8691 * In PostrgreSQL this fails if a simple converter like the following is used.
@@ -143,13 +148,50 @@ public void saveAndLoadAnEntityWithReference() {
143148 });
144149 }
145150
146- interface EntityWithBooleanRepository extends CrudRepository <EntityWithStringyBigDecimal , CustomId > {}
151+ @ Test // GH-1212
152+ void queryByEnumTypeIn () {
153+
154+ EntityWithStringyBigDecimal entityA = new EntityWithStringyBigDecimal ();
155+ entityA .direction = Direction .LEFT ;
156+ EntityWithStringyBigDecimal entityB = new EntityWithStringyBigDecimal ();
157+ entityB .direction = Direction .CENTER ;
158+ EntityWithStringyBigDecimal entityC = new EntityWithStringyBigDecimal ();
159+ entityC .direction = Direction .RIGHT ;
160+ repository .saveAll (asList (entityA , entityB , entityC ));
161+
162+ assertThat (repository .findByEnumTypeIn (asList (Direction .LEFT , Direction .RIGHT )))
163+ .extracting (entity -> entity .direction ).containsExactlyInAnyOrder (Direction .LEFT , Direction .RIGHT );
164+ }
165+
166+ @ Test // GH-1212
167+ void queryByEnumTypeEqual () {
168+
169+ EntityWithStringyBigDecimal entityA = new EntityWithStringyBigDecimal ();
170+ entityA .direction = Direction .LEFT ;
171+ EntityWithStringyBigDecimal entityB = new EntityWithStringyBigDecimal ();
172+ entityB .direction = Direction .CENTER ;
173+ EntityWithStringyBigDecimal entityC = new EntityWithStringyBigDecimal ();
174+ entityC .direction = Direction .RIGHT ;
175+ repository .saveAll (asList (entityA , entityB , entityC ));
176+
177+ assertThat (repository .findByEnumTypeIn (singletonList (Direction .CENTER ))).extracting (entity -> entity .direction )
178+ .containsExactly (Direction .CENTER );
179+ }
180+
181+ interface EntityWithStringyBigDecimalRepository extends CrudRepository <EntityWithStringyBigDecimal , CustomId > {
182+ @ Query ("SELECT * FROM ENTITY_WITH_STRINGY_BIG_DECIMAL WHERE DIRECTION IN (:types)" )
183+ List <EntityWithStringyBigDecimal > findByEnumTypeIn (List <Direction > types );
184+
185+ @ Query ("SELECT * FROM ENTITY_WITH_STRINGY_BIG_DECIMAL WHERE DIRECTION = :type" )
186+ List <EntityWithStringyBigDecimal > findByEnumType (Direction type );
187+ }
147188
148189 private static class EntityWithStringyBigDecimal {
149190
150191 @ Id CustomId id ;
151- String stringyNumber ;
192+ String stringyNumber = "1.0" ;
152193 OtherEntity reference ;
194+ Direction direction = Direction .CENTER ;
153195 }
154196
155197 private static class CustomId {
@@ -167,6 +209,10 @@ private static class OtherEntity {
167209 Date created ;
168210 }
169211
212+ enum Direction {
213+ LEFT , CENTER , RIGHT
214+ }
215+
170216 @ WritingConverter
171217 enum StringToBigDecimalConverter implements Converter <String , JdbcValue > {
172218
@@ -214,4 +260,64 @@ public CustomId convert(Number source) {
214260 }
215261 }
216262
263+ @ WritingConverter
264+ enum DirectionToIntegerConverter implements Converter <Direction , JdbcValue > {
265+
266+ INSTANCE ;
267+
268+ @ Override
269+ public JdbcValue convert (Direction source ) {
270+
271+ int integer ;
272+ switch (source ) {
273+ case LEFT :
274+ integer = -1 ;
275+ break ;
276+ case CENTER :
277+ integer = 0 ;
278+ break ;
279+ case RIGHT :
280+ integer = 1 ;
281+ break ;
282+ default :
283+ throw new IllegalArgumentException ();
284+ }
285+ return JdbcValue .of (integer , JDBCType .INTEGER );
286+ }
287+ }
288+
289+ @ ReadingConverter // Needed for Oracle since the JDBC driver returns BigDecimal on read
290+ enum NumberToDirectionConverter implements Converter <Number , Direction > {
291+
292+ INSTANCE ;
293+
294+ @ Override
295+ public Direction convert (Number source ) {
296+ int sourceAsInt = source .intValue ();
297+ if (sourceAsInt == 0 ) {
298+ return Direction .CENTER ;
299+ } else if (sourceAsInt < 0 ) {
300+ return Direction .LEFT ;
301+ } else {
302+ return Direction .RIGHT ;
303+ }
304+ }
305+ }
306+
307+ @ ReadingConverter
308+ enum IntegerToDirectionConverter implements Converter <Integer , Direction > {
309+
310+ INSTANCE ;
311+
312+ @ Override
313+ public Direction convert (Integer source ) {
314+ if (source == 0 ) {
315+ return Direction .CENTER ;
316+ } else if (source < 0 ) {
317+ return Direction .LEFT ;
318+ } else {
319+ return Direction .RIGHT ;
320+ }
321+ }
322+ }
217323}
0 commit comments