Skip to content

Commit ae86518

Browse files
schaudermp911de
authored andcommitted
Do not convert binary data in List<byte[]> to array SQL type.
byte[] is mapped to BINARY data and is not considered tuple data. The explicit check for byte[] is not very nice but matches the special handling in MappingJdbcConverter.writeJdbcValue Closes #1900 Original pull request: #1903
1 parent b3040a1 commit ae86518

10 files changed

+77
-22
lines changed

Diff for: spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
9292
public StringBasedJdbcQuery(JdbcQueryMethod queryMethod, NamedParameterJdbcOperations operations,
9393
@Nullable RowMapper<?> defaultRowMapper, JdbcConverter converter,
9494
QueryMethodEvaluationContextProvider evaluationContextProvider) {
95-
this(queryMethod.getRequiredQuery(), queryMethod, operations, result -> (RowMapper<Object>) defaultRowMapper, converter, evaluationContextProvider);
95+
this(queryMethod.getRequiredQuery(), queryMethod, operations, result -> (RowMapper<Object>) defaultRowMapper,
96+
converter, evaluationContextProvider);
9697
}
9798

9899
/**
@@ -244,7 +245,7 @@ private JdbcValue writeValue(@Nullable Object value, TypeInformation<?> typeInfo
244245
TypeInformation<?> actualType = typeInformation.getActualType();
245246

246247
// tuple-binding
247-
if (actualType != null && actualType.getType().isArray()) {
248+
if (actualType != null && actualType.getType().isArray() && !actualType.getType().equals(byte[].class)) {
248249

249250
TypeInformation<?> nestedElementType = actualType.getRequiredActualType();
250251
return writeCollection(collection, parameter.getActualSqlType(),

Diff for: spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java

+58-12
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.junit.jupiter.params.ParameterizedTest;
4242
import org.junit.jupiter.params.provider.Arguments;
4343
import org.junit.jupiter.params.provider.MethodSource;
44-
4544
import org.springframework.beans.factory.annotation.Autowired;
4645
import org.springframework.beans.factory.config.PropertiesFactoryBean;
4746
import org.springframework.context.ApplicationListener;
@@ -51,23 +50,13 @@
5150
import org.springframework.core.io.ClassPathResource;
5251
import org.springframework.dao.IncorrectResultSizeDataAccessException;
5352
import org.springframework.data.annotation.Id;
54-
import org.springframework.data.domain.Example;
55-
import org.springframework.data.domain.ExampleMatcher;
56-
import org.springframework.data.domain.Limit;
57-
import org.springframework.data.domain.Page;
58-
import org.springframework.data.domain.PageRequest;
59-
import org.springframework.data.domain.Pageable;
60-
import org.springframework.data.domain.ScrollPosition;
61-
import org.springframework.data.domain.Slice;
62-
import org.springframework.data.domain.Sort;
63-
import org.springframework.data.domain.Window;
53+
import org.springframework.data.domain.*;
6454
import org.springframework.data.jdbc.core.mapping.AggregateReference;
6555
import org.springframework.data.jdbc.repository.query.Modifying;
6656
import org.springframework.data.jdbc.repository.query.Query;
6757
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
6858
import org.springframework.data.jdbc.testing.ConditionalOnDatabase;
6959
import org.springframework.data.jdbc.testing.DatabaseType;
70-
import org.springframework.data.jdbc.testing.EnabledOnDatabase;
7160
import org.springframework.data.jdbc.testing.EnabledOnFeature;
7261
import org.springframework.data.jdbc.testing.IntegrationTest;
7362
import org.springframework.data.jdbc.testing.TestConfiguration;
@@ -1357,6 +1346,52 @@ void queryWithTupleIn() {
13571346
assertThat(result).containsOnly(two);
13581347
}
13591348

1349+
@Test // GH-1900
1350+
void queryByListOfByteArray() {
1351+
1352+
byte[] oneBytes = { 1, 2, 3, 4, 5, 6, 7, 8 };
1353+
DummyEntity one = createDummyEntity("one");
1354+
one.setBytes(oneBytes);
1355+
one = repository.save(one);
1356+
1357+
byte[] twoBytes = { 8, 7, 6, 5, 4, 3, 2, 1 };
1358+
DummyEntity two = createDummyEntity("two");
1359+
two.setBytes(twoBytes);
1360+
two = repository.save(two);
1361+
1362+
byte[] threeBytes = { 3, 3, 3, 3, 3, 3, 3, 3 };
1363+
DummyEntity three = createDummyEntity("three");
1364+
three.setBytes(threeBytes);
1365+
three = repository.save(three);
1366+
1367+
List<DummyEntity> result = repository.findByBytesIn(List.of(threeBytes, oneBytes));
1368+
1369+
assertThat(result).extracting("idProp").containsExactlyInAnyOrder(one.idProp, three.idProp);
1370+
}
1371+
1372+
@Test // GH-1900
1373+
void queryByByteArray() {
1374+
1375+
byte[] oneBytes = { 1, 2, 3, 4, 5, 6, 7, 8 };
1376+
DummyEntity one = createDummyEntity("one");
1377+
one.setBytes(oneBytes);
1378+
one = repository.save(one);
1379+
1380+
byte[] twoBytes = { 8, 7, 6, 5, 4, 3, 2, 1 };
1381+
DummyEntity two = createDummyEntity("two");
1382+
two.setBytes(twoBytes);
1383+
two = repository.save(two);
1384+
1385+
byte[] threeBytes = { 3, 3, 3, 3, 3, 3, 3, 3 };
1386+
DummyEntity three = createDummyEntity("three");
1387+
three.setBytes(threeBytes);
1388+
three = repository.save(three);
1389+
1390+
List<DummyEntity> result = repository.findByBytes(twoBytes);
1391+
1392+
assertThat(result).extracting("idProp").containsExactly(two.idProp);
1393+
}
1394+
13601395
private Root createRoot(String namePrefix) {
13611396

13621397
return new Root(null, namePrefix,
@@ -1487,6 +1522,12 @@ interface DummyEntityRepository extends CrudRepository<DummyEntity, Long>, Query
14871522

14881523
@Query("SELECT * FROM DUMMY_ENTITY WHERE (ID_PROP, NAME) IN (:tuples)")
14891524
List<DummyEntity> findByListInTuple(List<Object[]> tuples);
1525+
1526+
@Query("SELECT * FROM DUMMY_ENTITY WHERE BYTES IN (:bytes)")
1527+
List<DummyEntity> findByBytesIn(List<byte[]> bytes);
1528+
1529+
@Query("SELECT * FROM DUMMY_ENTITY WHERE BYTES = :bytes")
1530+
List<DummyEntity> findByBytes(byte[] bytes);
14901531
}
14911532

14921533
interface RootRepository extends ListCrudRepository<Root, Long> {
@@ -1810,6 +1851,7 @@ static class DummyEntity {
18101851
boolean flag;
18111852
AggregateReference<DummyEntity, Long> ref;
18121853
Direction direction;
1854+
byte[] bytes = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
18131855

18141856
public DummyEntity(String name) {
18151857
this.name = name;
@@ -1890,6 +1932,10 @@ public int hashCode() {
18901932
return Objects.hash(name, pointInTime, offsetDateTime, idProp, flag, ref, direction);
18911933
}
18921934

1935+
public void setBytes(byte[] bytes) {
1936+
this.bytes = bytes;
1937+
}
1938+
18931939
@Override
18941940
public String toString() {
18951941
return "DummyEntity{" + "name='" + name + '\'' + ", idProp=" + idProp + '}';

Diff for: spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-db2.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ CREATE TABLE dummy_entity
1212
OFFSET_DATE_TIME TIMESTAMP, -- with time zone is only supported with z/OS
1313
FLAG BOOLEAN,
1414
REF BIGINT,
15-
DIRECTION VARCHAR(100)
15+
DIRECTION VARCHAR(100),
16+
BYTES BINARY(8)
1617
);
1718

1819
CREATE TABLE ROOT

Diff for: spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-h2.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ CREATE TABLE dummy_entity
66
OFFSET_DATE_TIME TIMESTAMP WITH TIME ZONE,
77
FLAG BOOLEAN,
88
REF BIGINT,
9-
DIRECTION VARCHAR(100)
9+
DIRECTION VARCHAR(100),
10+
BYTES BINARY(8)
1011
);
1112

1213
CREATE TABLE ROOT

Diff for: spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ CREATE TABLE dummy_entity
66
OFFSET_DATE_TIME TIMESTAMP WITH TIME ZONE,
77
FLAG BOOLEAN,
88
REF BIGINT,
9-
DIRECTION VARCHAR(100)
9+
DIRECTION VARCHAR(100),
10+
BYTES BINARY(8)
1011
);
1112

1213
CREATE TABLE ROOT

Diff for: spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mariadb.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ CREATE TABLE dummy_entity
66
OFFSET_DATE_TIME TIMESTAMP(3),
77
FLAG BOOLEAN,
88
REF BIGINT,
9-
DIRECTION VARCHAR(100)
9+
DIRECTION VARCHAR(100),
10+
BYTES BINARY(8)
1011
);
1112

1213
CREATE TABLE ROOT

Diff for: spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mssql.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ CREATE TABLE dummy_entity
1212
OFFSET_DATE_TIME DATETIMEOFFSET,
1313
FLAG BIT,
1414
REF BIGINT,
15-
DIRECTION VARCHAR(100)
15+
DIRECTION VARCHAR(100),
16+
BYTES VARBINARY(8)
1617
);
1718

1819
CREATE TABLE ROOT

Diff for: spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ CREATE TABLE DUMMY_ENTITY
99
OFFSET_DATE_TIME TIMESTAMP(3) DEFAULT NULL,
1010
FLAG BIT(1),
1111
REF BIGINT,
12-
DIRECTION VARCHAR(100)
12+
DIRECTION VARCHAR(100),
13+
BYTES BINARY(8)
1314
);
1415

1516
CREATE TABLE ROOT

Diff for: spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-oracle.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ CREATE TABLE DUMMY_ENTITY
1212
OFFSET_DATE_TIME TIMESTAMP WITH TIME ZONE,
1313
FLAG NUMBER(1,0),
1414
REF NUMBER,
15-
DIRECTION VARCHAR2(100)
15+
DIRECTION VARCHAR2(100),
16+
BYTES RAW(8)
1617
);
1718

1819
CREATE TABLE ROOT

Diff for: spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ CREATE TABLE dummy_entity
1212
OFFSET_DATE_TIME TIMESTAMP WITH TIME ZONE,
1313
FLAG BOOLEAN,
1414
REF BIGINT,
15-
DIRECTION VARCHAR(100)
15+
DIRECTION VARCHAR(100),
16+
BYTES BYTEA
1617
);
1718

1819
CREATE TABLE ROOT

0 commit comments

Comments
 (0)