Properly convert primitive array arguments.
Closes #945 Original pull request: #949.
This commit is contained in:
committed by
Mark Paluch
parent
80da756a42
commit
a55bdb46cc
@@ -41,4 +41,97 @@ class ArrayUtil {
|
|||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Byte[] toObjectArray(byte[] primitiveArray) {
|
||||||
|
|
||||||
|
Byte[] objects = new Byte[primitiveArray.length];
|
||||||
|
for (int i = 0; i < primitiveArray.length; i++) {
|
||||||
|
objects[i] = primitiveArray[i];
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Short[] toObjectArray(short[] primitiveArray) {
|
||||||
|
|
||||||
|
Short[] objects = new Short[primitiveArray.length];
|
||||||
|
for (int i = 0; i < primitiveArray.length; i++) {
|
||||||
|
objects[i] = primitiveArray[i];
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Character[] toObjectArray(char[] primitiveArray) {
|
||||||
|
|
||||||
|
Character[] objects = new Character[primitiveArray.length];
|
||||||
|
for (int i = 0; i < primitiveArray.length; i++) {
|
||||||
|
objects[i] = primitiveArray[i];
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Integer[] toObjectArray(int[] primitiveArray) {
|
||||||
|
|
||||||
|
Integer[] objects = new Integer[primitiveArray.length];
|
||||||
|
for (int i = 0; i < primitiveArray.length; i++) {
|
||||||
|
objects[i] = primitiveArray[i];
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Long[] toObjectArray(long[] primitiveArray) {
|
||||||
|
|
||||||
|
Long[] objects = new Long[primitiveArray.length];
|
||||||
|
for (int i = 0; i < primitiveArray.length; i++) {
|
||||||
|
objects[i] = primitiveArray[i];
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Float[] toObjectArray(float[] primitiveArray) {
|
||||||
|
|
||||||
|
Float[] objects = new Float[primitiveArray.length];
|
||||||
|
for (int i = 0; i < primitiveArray.length; i++) {
|
||||||
|
objects[i] = primitiveArray[i];
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Double[] toObjectArray(double[] primitiveArray) {
|
||||||
|
|
||||||
|
Double[] objects = new Double[primitiveArray.length];
|
||||||
|
for (int i = 0; i < primitiveArray.length; i++) {
|
||||||
|
objects[i] = primitiveArray[i];
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object[] convertToObjectArray(Object unknownArray) {
|
||||||
|
|
||||||
|
Class<?> componentType = unknownArray.getClass().getComponentType();
|
||||||
|
|
||||||
|
if (componentType.isPrimitive()) {
|
||||||
|
if (componentType == byte.class) {
|
||||||
|
return toObjectArray((byte[]) unknownArray);
|
||||||
|
}
|
||||||
|
if (componentType == short.class) {
|
||||||
|
return toObjectArray((short[]) unknownArray);
|
||||||
|
}
|
||||||
|
if (componentType == char.class) {
|
||||||
|
return toObjectArray((char[]) unknownArray);
|
||||||
|
}
|
||||||
|
if (componentType == int.class) {
|
||||||
|
return toObjectArray((int[]) unknownArray);
|
||||||
|
}
|
||||||
|
if (componentType == long.class) {
|
||||||
|
return toObjectArray((long[]) unknownArray);
|
||||||
|
}
|
||||||
|
if (componentType == float.class) {
|
||||||
|
return toObjectArray((float[]) unknownArray);
|
||||||
|
}
|
||||||
|
if (componentType == double.class) {
|
||||||
|
return toObjectArray((double[]) unknownArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (Object[]) unknownArray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,7 +297,9 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
|
|||||||
|
|
||||||
Class<?> componentType = convertedValue.getClass().getComponentType();
|
Class<?> componentType = convertedValue.getClass().getComponentType();
|
||||||
if (componentType != byte.class && componentType != Byte.class) {
|
if (componentType != byte.class && componentType != Byte.class) {
|
||||||
return JdbcValue.of(typeFactory.createArray((Object[]) convertedValue), JDBCType.ARRAY);
|
|
||||||
|
Object[] objectArray = ArrayUtil.convertToObjectArray(convertedValue);
|
||||||
|
return JdbcValue.of(typeFactory.createArray(objectArray), JDBCType.ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (componentType == Byte.class) {
|
if (componentType == Byte.class) {
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
package org.springframework.data.jdbc.core.convert;
|
package org.springframework.data.jdbc.core.convert;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.*;
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.sql.Array;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@@ -35,8 +37,10 @@ import org.junit.Test;
|
|||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.jdbc.core.mapping.AggregateReference;
|
import org.springframework.data.jdbc.core.mapping.AggregateReference;
|
||||||
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||||
|
import org.springframework.data.jdbc.support.JdbcUtil;
|
||||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||||
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
|
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
|
||||||
|
import org.springframework.data.relational.core.sql.IdentifierProcessing;
|
||||||
import org.springframework.data.util.ClassTypeInformation;
|
import org.springframework.data.util.ClassTypeInformation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,9 +51,15 @@ import org.springframework.data.util.ClassTypeInformation;
|
|||||||
public class BasicJdbcConverterUnitTests {
|
public class BasicJdbcConverterUnitTests {
|
||||||
|
|
||||||
JdbcMappingContext context = new JdbcMappingContext();
|
JdbcMappingContext context = new JdbcMappingContext();
|
||||||
BasicJdbcConverter converter = new BasicJdbcConverter(context, (identifier, path) -> {
|
StubbedJdbcTypeFactory typeFactory = new StubbedJdbcTypeFactory();
|
||||||
throw new UnsupportedOperationException();
|
BasicJdbcConverter converter = new BasicJdbcConverter( //
|
||||||
});
|
context, //
|
||||||
|
(identifier, path) -> {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}, //
|
||||||
|
new JdbcCustomConversions(), //
|
||||||
|
typeFactory, IdentifierProcessing.ANSI //
|
||||||
|
);
|
||||||
|
|
||||||
@Test // DATAJDBC-104, DATAJDBC-1384
|
@Test // DATAJDBC-104, DATAJDBC-1384
|
||||||
public void testTargetTypesForPropertyType() {
|
public void testTargetTypesForPropertyType() {
|
||||||
@@ -110,14 +120,25 @@ public class BasicJdbcConverterUnitTests {
|
|||||||
LocalDateTime testLocalDateTime = LocalDateTime.of(2001, 2, 3, 4, 5, 6, 123456789);
|
LocalDateTime testLocalDateTime = LocalDateTime.of(2001, 2, 3, 4, 5, 6, 123456789);
|
||||||
checkConversionToTimestampAndBack(softly, persistentEntity, "localDateTime", testLocalDateTime);
|
checkConversionToTimestampAndBack(softly, persistentEntity, "localDateTime", testLocalDateTime);
|
||||||
checkConversionToTimestampAndBack(softly, persistentEntity, "localDate", LocalDate.of(2001, 2, 3));
|
checkConversionToTimestampAndBack(softly, persistentEntity, "localDate", LocalDate.of(2001, 2, 3));
|
||||||
checkConversionToTimestampAndBack(softly, persistentEntity, "localTime", LocalTime.of(1, 2, 3,123456789));
|
checkConversionToTimestampAndBack(softly, persistentEntity, "localTime", LocalTime.of(1, 2, 3, 123456789));
|
||||||
checkConversionToTimestampAndBack(softly, persistentEntity, "instant", testLocalDateTime.toInstant(ZoneOffset.UTC));
|
checkConversionToTimestampAndBack(softly, persistentEntity, "instant",
|
||||||
|
testLocalDateTime.toInstant(ZoneOffset.UTC));
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkConversionToTimestampAndBack(SoftAssertions softly, RelationalPersistentEntity<?> persistentEntity, String propertyName,
|
@Test // #945
|
||||||
Object value) {
|
public void conversionOfPrimitiveArrays() {
|
||||||
|
|
||||||
|
int[] ints = { 1, 2, 3, 4, 5 };
|
||||||
|
JdbcValue converted = converter.writeJdbcValue(ints, ints.getClass(), JdbcUtil.sqlTypeFor(ints.getClass()));
|
||||||
|
|
||||||
|
assertThat(converted.getValue()).isInstanceOf(Array.class);
|
||||||
|
assertThat(typeFactory.arraySource).containsExactly(1, 2, 3, 4, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkConversionToTimestampAndBack(SoftAssertions softly, RelationalPersistentEntity<?> persistentEntity,
|
||||||
|
String propertyName, Object value) {
|
||||||
|
|
||||||
RelationalPersistentProperty property = persistentEntity.getRequiredPersistentProperty(propertyName);
|
RelationalPersistentProperty property = persistentEntity.getRequiredPersistentProperty(propertyName);
|
||||||
|
|
||||||
@@ -165,4 +186,14 @@ public class BasicJdbcConverterUnitTests {
|
|||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static class OtherEntity {}
|
private static class OtherEntity {}
|
||||||
|
|
||||||
|
private static class StubbedJdbcTypeFactory implements JdbcTypeFactory {
|
||||||
|
public Object[] arraySource;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Array createArray(Object[] value) {
|
||||||
|
arraySource = value;
|
||||||
|
return mock(Array.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user