DATAJDBC-327 - Polishing.
Extend Javadoc. Reorder constructors in the order of their parameter number. Add missing assertions. Introduce utility to create predicates. Remove unused fields. Add since tags. Reformat. Original pull request: #123.
This commit is contained in:
@@ -65,24 +65,44 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
|
||||
private final @NonNull NamedParameterJdbcOperations operations;
|
||||
private final @NonNull DataAccessStrategy accessStrategy;
|
||||
|
||||
/**
|
||||
* Creates a {@link DefaultDataAccessStrategy} which references it self for resolution of recursive data accesses.
|
||||
* Only suitable if this is the only access strategy in use.
|
||||
*
|
||||
* @param sqlGeneratorSource must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @param converter must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
*/
|
||||
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, RelationalMappingContext context,
|
||||
JdbcConverter converter, NamedParameterJdbcOperations operations, @Nullable DataAccessStrategy accessStrategy) {
|
||||
JdbcConverter converter, NamedParameterJdbcOperations operations) {
|
||||
this(sqlGeneratorSource, context, converter, operations, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link DefaultDataAccessStrategy}
|
||||
*
|
||||
* @param sqlGeneratorSource must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @param converter must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
* @param mappingAccessStrategy can be {@literal null}.
|
||||
* @since 1.1
|
||||
*/
|
||||
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, RelationalMappingContext context,
|
||||
JdbcConverter converter, NamedParameterJdbcOperations operations,
|
||||
@Nullable DataAccessStrategy mappingAccessStrategy) {
|
||||
|
||||
Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null");
|
||||
Assert.notNull(context, "RelationalMappingContext must not be null");
|
||||
Assert.notNull(converter, "JdbcConverter must not be null");
|
||||
Assert.notNull(operations, "NamedParameterJdbcOperations must not be null");
|
||||
|
||||
this.sqlGeneratorSource = sqlGeneratorSource;
|
||||
this.context = context;
|
||||
this.converter = converter;
|
||||
this.operations = operations;
|
||||
this.accessStrategy = accessStrategy == null ? this : accessStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link DefaultDataAccessStrategy} which references it self for resolution of recursive data accesses.
|
||||
* Only suitable if this is the only access strategy in use.
|
||||
*/
|
||||
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, RelationalMappingContext context,
|
||||
JdbcConverter converter, NamedParameterJdbcOperations operations) {
|
||||
|
||||
this(sqlGeneratorSource, context, converter, operations, null);
|
||||
this.accessStrategy = mappingAccessStrategy == null ? this : mappingAccessStrategy;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -104,7 +124,8 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
|
||||
KeyHolder holder = new GeneratedKeyHolder();
|
||||
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(domainType);
|
||||
|
||||
MapSqlParameterSource parameterSource = getParameterSource(instance, persistentEntity, "", PersistentProperty::isIdProperty);
|
||||
MapSqlParameterSource parameterSource = getParameterSource(instance, persistentEntity, "",
|
||||
PersistentProperty::isIdProperty);
|
||||
|
||||
identifier.forEach((name, value, type) -> addConvertedPropertyValue(parameterSource, name, value, type));
|
||||
|
||||
@@ -134,7 +155,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
|
||||
RelationalPersistentEntity<S> persistentEntity = getRequiredPersistentEntity(domainType);
|
||||
|
||||
return operations.update(sql(domainType).getUpdate(),
|
||||
getParameterSource(instance, persistentEntity, "", property -> false)) != 0;
|
||||
getParameterSource(instance, persistentEntity, "", Predicates.includeAll())) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -289,7 +310,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
|
||||
}
|
||||
|
||||
private <S, T> MapSqlParameterSource getParameterSource(S instance, RelationalPersistentEntity<S> persistentEntity,
|
||||
String prefix, Predicate<RelationalPersistentProperty> skipProperty) {
|
||||
String prefix, Predicate<RelationalPersistentProperty> skipProperty) {
|
||||
|
||||
MapSqlParameterSource parameters = new MapSqlParameterSource();
|
||||
|
||||
@@ -445,4 +466,19 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
|
||||
private SqlGenerator sql(Class<?> domainType) {
|
||||
return sqlGeneratorSource.getSqlGenerator(domainType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to create {@link Predicate}s.
|
||||
*/
|
||||
static class Predicates {
|
||||
|
||||
/**
|
||||
* Include all {@link Predicate} returning {@literal false} to never skip a property.
|
||||
*
|
||||
* @return the include all {@link Predicate}.
|
||||
*/
|
||||
static Predicate<RelationalPersistentProperty> includeAll() {
|
||||
return it -> false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,19 @@ import lombok.experimental.UtilityClass;
|
||||
* A collection of utility methods for dealing with arrays.
|
||||
*
|
||||
* @author Jens Schauder
|
||||
* @since 1.1
|
||||
*/
|
||||
@UtilityClass
|
||||
class ArrayUtil {
|
||||
|
||||
/**
|
||||
* Convertes an {@code Byte[]} into a {@code byte[]}
|
||||
* @param byteArray the array to be converted. Must not be {@literal null}.
|
||||
* Converts an {@code Byte[]} into a {@code byte[]}.
|
||||
*
|
||||
* @return a {@code byte[]} of same size with the unboxed values of the input array. Guaranteed to be not {@literal null}.
|
||||
* @param byteArray the array to be converted. Must not be {@literal null}.
|
||||
* @return a {@code byte[]} of same size with the unboxed values of the input array. Guaranteed to be not
|
||||
* {@literal null}.
|
||||
*/
|
||||
static Object toPrimitiveByteArray(Byte[] byteArray) {
|
||||
static byte[] toPrimitiveByteArray(Byte[] byteArray) {
|
||||
|
||||
byte[] bytes = new byte[byteArray.length];
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.data.convert.CustomConversions;
|
||||
import org.springframework.data.jdbc.core.mapping.AggregateReference;
|
||||
@@ -35,6 +36,7 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProp
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link RelationalConverter} that uses a {@link MappingContext} to apply basic conversion of relational values to
|
||||
@@ -54,43 +56,54 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
|
||||
|
||||
private final JdbcTypeFactory typeFactory;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicRelationalConverter} given {@link MappingContext} and a
|
||||
* {@link JdbcTypeFactory#unsupported() no-op type factory} throwing {@link UnsupportedOperationException} on type
|
||||
* creation. Use {@link #BasicJdbcConverter(MappingContext, JdbcTypeFactory)} to convert arrays and large objects into
|
||||
* JDBC-specific types.
|
||||
*
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
public BasicJdbcConverter(
|
||||
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context) {
|
||||
this(context, JdbcTypeFactory.unsupported());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicRelationalConverter} given {@link MappingContext}.
|
||||
*
|
||||
* @param context must not be {@literal null}. org.springframework.data.jdbc.core.DefaultDataAccessStrategyUnitTests
|
||||
* @param typeFactory
|
||||
* @param context must not be {@literal null}.
|
||||
* @param typeFactory must not be {@literal null}
|
||||
* @since 1.1
|
||||
*/
|
||||
public BasicJdbcConverter(
|
||||
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context,
|
||||
JdbcTypeFactory typeFactory) {
|
||||
|
||||
super(context);
|
||||
|
||||
Assert.notNull(typeFactory, "JdbcTypeFactory must not be null");
|
||||
|
||||
this.typeFactory = typeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicRelationalConverter} given {@link MappingContext} and {@link CustomConversions}.
|
||||
*
|
||||
* Creates a new {@link BasicRelationalConverter} given {@link MappingContext}, {@link CustomConversions}, and
|
||||
* {@link JdbcTypeFactory}.
|
||||
*
|
||||
* @param context must not be {@literal null}.
|
||||
* @param conversions must not be {@literal null}.
|
||||
* @param typeFactory
|
||||
* @param typeFactory must not be {@literal null}
|
||||
* @since 1.1
|
||||
*/
|
||||
public BasicJdbcConverter(
|
||||
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context,
|
||||
CustomConversions conversions, JdbcTypeFactory typeFactory) {
|
||||
super(context, conversions);
|
||||
this.typeFactory = typeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicRelationalConverter} given {@link MappingContext}.
|
||||
*
|
||||
* @param context must not be {@literal null}. org.springframework.data.jdbc.core.DefaultDataAccessStrategyUnitTests
|
||||
* @deprecated use one of the constructors with {@link JdbcTypeFactory} parameter.
|
||||
*/
|
||||
@Deprecated
|
||||
public BasicJdbcConverter(
|
||||
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context) {
|
||||
this(context, JdbcTypeFactory.unsupported());
|
||||
super(context, conversions);
|
||||
|
||||
Assert.notNull(typeFactory, "JdbcTypeFactory must not be null");
|
||||
this.typeFactory = typeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,6 +199,11 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
|
||||
return customWriteTarget.isPresent() && customWriteTarget.get().isAssignableFrom(JdbcValue.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jdbc.core.convert.JdbcConverter#writeValue(java.lang.Object, java.lang.Class, int)
|
||||
*/
|
||||
@Override
|
||||
public JdbcValue writeJdbcValue(@Nullable Object value, Class<?> columnType, int sqlType) {
|
||||
|
||||
JdbcValue jdbcValue = tryToConvertToJdbcValue(value);
|
||||
@@ -209,16 +227,15 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
|
||||
}
|
||||
|
||||
return JdbcValue.of(convertedValue, JDBCType.BINARY);
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JdbcValue tryToConvertToJdbcValue(@Nullable Object value) {
|
||||
|
||||
JdbcValue jdbcValue = null;
|
||||
if (canWriteAsJdbcValue(value)) {
|
||||
jdbcValue = (JdbcValue) writeValue(value, ClassTypeInformation.from(JdbcValue.class));
|
||||
return (JdbcValue) writeValue(value, ClassTypeInformation.from(JdbcValue.class));
|
||||
}
|
||||
|
||||
return jdbcValue;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,17 @@
|
||||
*/
|
||||
package org.springframework.data.jdbc.core.convert;
|
||||
|
||||
import java.sql.Array;
|
||||
import java.sql.JDBCType;
|
||||
|
||||
import org.springframework.data.jdbc.support.JdbcUtil;
|
||||
import org.springframework.jdbc.core.ConnectionCallback;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.sql.Array;
|
||||
import java.sql.JDBCType;
|
||||
|
||||
/**
|
||||
* A {@link JdbcTypeFactory} that performs the conversion by utilizing {@link JdbcOperations#execute(ConnectionCallback)}.
|
||||
* A {@link JdbcTypeFactory} that performs the conversion by utilizing
|
||||
* {@link JdbcOperations#execute(ConnectionCallback)}.
|
||||
*
|
||||
* @author Jens Schauder
|
||||
* @since 1.1
|
||||
@@ -33,7 +34,15 @@ public class DefaultJdbcTypeFactory implements JdbcTypeFactory {
|
||||
|
||||
private final JdbcOperations operations;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultJdbcTypeFactory}.
|
||||
*
|
||||
* @param operations must not be {@literal null}.
|
||||
*/
|
||||
public DefaultJdbcTypeFactory(JdbcOperations operations) {
|
||||
|
||||
Assert.notNull(operations, "JdbcOperations must not be null");
|
||||
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* JDBC-specific conversion classes.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.data.jdbc.core.convert;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* Core JDBC implementation.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.data.jdbc.core;
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class JdbcUtil {
|
||||
|
||||
/**
|
||||
* Converts a {@link JDBCType} to an {@code int} value as defined in {@link Types}.
|
||||
*
|
||||
*
|
||||
* @param jdbcType value to be converted. May be {@literal null}.
|
||||
* @return One of the values defined in {@link Types} or {@link JdbcUtils#TYPE_UNKNOWN}.
|
||||
*/
|
||||
@@ -98,7 +98,7 @@ public class JdbcUtil {
|
||||
/**
|
||||
* Converts a value defined in {@link Types} into a {@link JDBCType} instance or {@literal null} if the value is
|
||||
* {@link JdbcUtils#TYPE_UNKNOWN}
|
||||
*
|
||||
*
|
||||
* @param sqlType One of the values defined in {@link Types} or {@link JdbcUtils#TYPE_UNKNOWN}.
|
||||
* @return a matching {@link JDBCType} instance or {@literal null}.
|
||||
*/
|
||||
@@ -121,7 +121,6 @@ public class JdbcUtil {
|
||||
*/
|
||||
@Nullable
|
||||
public static JDBCType jdbcTypeFor(Class<?> type) {
|
||||
|
||||
return jdbcTypeFor(sqlTypeFor(type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.HashMap;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
@@ -37,6 +38,7 @@ import org.springframework.data.jdbc.core.convert.JdbcConverter;
|
||||
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
|
||||
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
@@ -52,10 +54,11 @@ public class DefaultDataAccessStrategyUnitTests {
|
||||
public static final long ID_FROM_ADDITIONAL_VALUES = 23L;
|
||||
public static final long ORIGINAL_ID = 4711L;
|
||||
|
||||
NamedParameterJdbcOperations jdbcOperations = mock(NamedParameterJdbcOperations.class);
|
||||
NamedParameterJdbcOperations namedJdbcOperations = mock(NamedParameterJdbcOperations.class);
|
||||
JdbcOperations jdbcOperations = mock(JdbcOperations.class);
|
||||
RelationalMappingContext context = new JdbcMappingContext();
|
||||
JdbcConverter converter = new BasicJdbcConverter(context, new JdbcCustomConversions(),
|
||||
new DefaultJdbcTypeFactory(jdbcOperations.getJdbcOperations()));
|
||||
new DefaultJdbcTypeFactory(jdbcOperations));
|
||||
HashMap<String, Object> additionalParameters = new HashMap<>();
|
||||
ArgumentCaptor<SqlParameterSource> paramSourceCaptor = ArgumentCaptor.forClass(SqlParameterSource.class);
|
||||
|
||||
@@ -63,7 +66,7 @@ public class DefaultDataAccessStrategyUnitTests {
|
||||
new SqlGeneratorSource(context), //
|
||||
context, //
|
||||
converter, //
|
||||
jdbcOperations);
|
||||
namedJdbcOperations);
|
||||
|
||||
@Test // DATAJDBC-146
|
||||
public void additionalParameterForIdDoesNotLeadToDuplicateParameters() {
|
||||
@@ -72,7 +75,7 @@ public class DefaultDataAccessStrategyUnitTests {
|
||||
|
||||
accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, additionalParameters);
|
||||
|
||||
verify(jdbcOperations).update(eq("INSERT INTO dummy_entity (id) VALUES (:id)"), paramSourceCaptor.capture(),
|
||||
verify(namedJdbcOperations).update(eq("INSERT INTO dummy_entity (id) VALUES (:id)"), paramSourceCaptor.capture(),
|
||||
any(KeyHolder.class));
|
||||
}
|
||||
|
||||
@@ -85,7 +88,7 @@ public class DefaultDataAccessStrategyUnitTests {
|
||||
|
||||
accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, additionalParameters);
|
||||
|
||||
verify(jdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class));
|
||||
verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class));
|
||||
|
||||
assertThat(sqlCaptor.getValue()) //
|
||||
.containsSequence("INSERT INTO dummy_entity (", "id", ") VALUES (", ":id", ")") //
|
||||
@@ -98,13 +101,13 @@ public class DefaultDataAccessStrategyUnitTests {
|
||||
|
||||
JdbcConverter converter = new BasicJdbcConverter(context,
|
||||
new JdbcCustomConversions(Arrays.asList(BooleanToStringConverter.INSTANCE, StringToBooleanConverter.INSTANCE)),
|
||||
new DefaultJdbcTypeFactory(jdbcOperations.getJdbcOperations()));
|
||||
new DefaultJdbcTypeFactory(jdbcOperations));
|
||||
|
||||
DefaultDataAccessStrategy accessStrategy = new DefaultDataAccessStrategy( //
|
||||
new SqlGeneratorSource(context), //
|
||||
context, //
|
||||
converter, //
|
||||
jdbcOperations);
|
||||
namedJdbcOperations);
|
||||
|
||||
ArgumentCaptor<String> sqlCaptor = ArgumentCaptor.forClass(String.class);
|
||||
|
||||
@@ -112,7 +115,7 @@ public class DefaultDataAccessStrategyUnitTests {
|
||||
|
||||
accessStrategy.insert(entity, EntityWithBoolean.class, new HashMap<>());
|
||||
|
||||
verify(jdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class));
|
||||
verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class));
|
||||
|
||||
assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(ORIGINAL_ID);
|
||||
assertThat(paramSourceCaptor.getValue().getValue("flag")).isEqualTo("T");
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.junit.Assume;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -422,7 +423,7 @@ public class JdbcAggregateTemplateIntegrationTests {
|
||||
@Test // DATAJDBC-327
|
||||
public void saveAndLoadAnEntityWithByteArray() {
|
||||
ByteArrayOwner owner = new ByteArrayOwner();
|
||||
owner.binaryData = new byte[]{1, 23, 42};
|
||||
owner.binaryData = new byte[] { 1, 23, 42 };
|
||||
|
||||
ByteArrayOwner saved = template.save(owner);
|
||||
|
||||
@@ -430,10 +431,9 @@ public class JdbcAggregateTemplateIntegrationTests {
|
||||
|
||||
assertThat(reloaded).isNotNull();
|
||||
assertThat(reloaded.id).isEqualTo(saved.id);
|
||||
assertThat(reloaded.binaryData).isEqualTo(new byte[]{1, 23, 42});
|
||||
assertThat(reloaded.binaryData).isEqualTo(new byte[] { 1, 23, 42 });
|
||||
}
|
||||
|
||||
|
||||
private static void assumeNot(String dbProfileName) {
|
||||
|
||||
Assume.assumeTrue("true"
|
||||
|
||||
@@ -38,12 +38,8 @@ import org.springframework.data.util.ClassTypeInformation;
|
||||
*/
|
||||
public class BasicRelationalConverterAggregateReferenceUnitTests {
|
||||
|
||||
SoftAssertions softly = new SoftAssertions();
|
||||
|
||||
ConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
JdbcMappingContext context = new JdbcMappingContext();
|
||||
RelationalConverter converter = new BasicJdbcConverter(context, JdbcTypeFactory.unsupported());
|
||||
RelationalConverter converter = new BasicJdbcConverter(context);
|
||||
|
||||
RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(DummyEntity.class);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2018 the original author or authors.
|
||||
* Copyright 2019 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.
|
||||
@@ -25,6 +25,7 @@ import java.util.Optional;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -84,23 +85,21 @@ public class JdbcRepositoryCustomConversionIntegrationTests {
|
||||
* In PostrgreSQL this fails if a simple converter like the following is used.
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
@WritingConverter enum PlainStringToBigDecimalConverter implements Converter<String, BigDecimal> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BigDecimal convert(@Nullable String source) {
|
||||
|
||||
return source == null ? null : new BigDecimal(source);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*
|
||||
* @WritingConverter
|
||||
* enum PlainStringToBigDecimalConverter implements Converter<String, BigDecimal> {
|
||||
*
|
||||
* INSTANCE;
|
||||
*
|
||||
* @Override
|
||||
* @Nullable
|
||||
* public BigDecimal convert(@Nullable String source) {
|
||||
*
|
||||
* return source == null ? null : new BigDecimal(source);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
@Test // DATAJDBC-327
|
||||
public void saveAndLoadAnEntity() {
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.assertj.core.groups.Tuple;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.jdbc.core.DefaultDataAccessStrategy;
|
||||
@@ -53,6 +54,7 @@ import org.springframework.data.relational.core.mapping.event.BeforeSaveEvent;
|
||||
import org.springframework.data.relational.core.mapping.event.Identifier;
|
||||
import org.springframework.data.relational.core.mapping.event.RelationalEvent;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
@@ -224,6 +226,7 @@ public class SimpleJdbcRepositoryEventsUnitTests {
|
||||
NamedParameterJdbcOperations operations = mock(NamedParameterJdbcOperations.class);
|
||||
when(operations.update(anyString(), any(SqlParameterSource.class), any(KeyHolder.class)))
|
||||
.thenAnswer(setIdInKeyHolder);
|
||||
when(operations.getJdbcOperations()).thenReturn(mock(JdbcOperations.class));
|
||||
return operations;
|
||||
}
|
||||
|
||||
|
||||
@@ -190,9 +190,9 @@ Converters should be annotated with `@ReadingConverter` or `@WritingConverter` i
|
||||
|
||||
==== JdbcValue
|
||||
|
||||
When setting bind parameters with a JDBC driver one may opt to provide a `java.sql.Types` constant value to denote the type of the parameter.
|
||||
If for a value this type need to be specified this can be done by using a writing converter as described in the previous section.
|
||||
This converter should convert to `JdbcValue` which has a field for the value and one of for the `JDBCType`.
|
||||
Value conversion uses `JdbcValue` to enrich values propagated to JDBC operations with a `java.sql.Types` type.
|
||||
Register a custom write converter if you need to specify a JDBC-specific type instead of using type derivation.
|
||||
This converter should convert the value to `JdbcValue` which has a field for the value and for the actual `JDBCType`.
|
||||
|
||||
[[jdbc.entity-persistence.naming-strategy]]
|
||||
=== `NamingStrategy`
|
||||
|
||||
Reference in New Issue
Block a user