diff --git a/pom.xml b/pom.xml
index 87b7e95ebe..01aba6d43c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-relational-parent
- 1.2.0.BUILD-SNAPSHOT
+ 1.2.0.DATAJDBC-431-SNAPSHOT
pom
Spring Data Relational Parent
diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml
index f2bbb72319..9afa9305bd 100644
--- a/spring-data-jdbc-distribution/pom.xml
+++ b/spring-data-jdbc-distribution/pom.xml
@@ -14,7 +14,7 @@
org.springframework.data
spring-data-relational-parent
- 1.2.0.BUILD-SNAPSHOT
+ 1.2.0.DATAJDBC-431-SNAPSHOT
../pom.xml
diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml
index 0904eb8136..de14dce478 100644
--- a/spring-data-jdbc/pom.xml
+++ b/spring-data-jdbc/pom.xml
@@ -5,7 +5,7 @@
4.0.0
spring-data-jdbc
- 1.2.0.BUILD-SNAPSHOT
+ 1.2.0.DATAJDBC-431-SNAPSHOT
Spring Data JDBC
Spring Data module for JDBC repositories.
@@ -14,7 +14,7 @@
org.springframework.data
spring-data-relational-parent
- 1.2.0.BUILD-SNAPSHOT
+ 1.2.0.DATAJDBC-431-SNAPSHOT
diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java
index a1319ddb5b..ec004609f5 100644
--- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java
+++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java
@@ -58,6 +58,7 @@ public interface DataAccessStrategy extends RelationResolver {
* @return the id generated by the database if any.
* @since 1.1
*/
+ @Nullable
default Object insert(T instance, Class domainType, Identifier identifier) {
return insert(instance, domainType, identifier.toMap());
}
diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java
index 3f54d1d3f0..ecef50c8f8 100644
--- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java
+++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java
@@ -313,7 +313,7 @@ public boolean existsById(Object id, Class domainType) {
return result;
}
- private MapSqlParameterSource getParameterSource(S instance, RelationalPersistentEntity persistentEntity,
+ private MapSqlParameterSource getParameterSource(@Nullable S instance, RelationalPersistentEntity persistentEntity,
String prefix, Predicate skipProperty) {
MapSqlParameterSource parameters = new MapSqlParameterSource();
@@ -323,7 +323,7 @@ private MapSqlParameterSource getParameterSource(S instance, RelationalPe
persistentEntity.doWithProperties((PropertyHandler) property -> {
- if (skipProperty.test(property)) {
+ if (skipProperty.test(property) || !property.isWritable()) {
return;
}
if (property.isEntity() && !property.isEmbedded()) {
@@ -418,7 +418,7 @@ private MapSqlParameterSource createIdParameterSource(Object id, Class do
}
private void addConvertedPropertyValue(MapSqlParameterSource parameterSource, RelationalPersistentProperty property,
- Object value, String paramName) {
+ @Nullable Object value, String paramName) {
JdbcValue jdbcValue = converter.writeJdbcValue( //
value, //
diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java
index c24d32ad8c..f7a93fca35 100644
--- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java
+++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java
@@ -29,7 +29,6 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import org.springframework.data.annotation.ReadOnlyProperty;
import org.springframework.data.jdbc.repository.support.SimpleJdbcRepository;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PropertyHandler;
@@ -623,7 +622,7 @@ private void initSimpleColumnName(RelationalPersistentProperty property, String
idColumnNames.add(columnName);
}
- if (!property.isWritable() || property.isAnnotationPresent(ReadOnlyProperty.class)) {
+ if (!property.isWritable()) {
readOnlyColumnNames.add(columnName);
}
}
diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java
index c388b46234..ac91b39c5e 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java
@@ -21,8 +21,10 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -41,8 +43,10 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.ReadOnlyProperty;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.testing.DatabaseProfileValueSource;
+import org.springframework.data.jdbc.testing.HsqlDbOnly;
import org.springframework.data.jdbc.testing.TestConfiguration;
import org.springframework.data.relational.core.conversion.RelationalConverter;
import org.springframework.data.relational.core.mapping.Column;
@@ -597,6 +601,20 @@ public void shouldDeleteChainOfMapsWithoutIds() {
});
}
+ @Test // DATAJDBC-431
+ @HsqlDbOnly
+ public void readOnlyGetsLoadedButNotWritten() {
+
+ WithReadOnly entity = new WithReadOnly();
+ entity.name = "Alfred";
+ entity.readOnly = "not used";
+
+ template.save(entity);
+
+ assertThat(
+ jdbcTemplate.queryForObject("SELECT read_only FROM with_read_only", Collections.emptyMap(), String.class)).isEqualTo("from-db");
+ }
+
private static NoIdMapChain4 createNoIdMapTree() {
NoIdMapChain4 chain4 = new NoIdMapChain4();
@@ -855,6 +873,13 @@ static class NoIdMapChain4 {
Map chain3 = new HashMap<>();
}
+ static class WithReadOnly {
+ @Id Long id;
+ String name;
+ @ReadOnlyProperty
+ String readOnly;
+ }
+
@Configuration
@Import(TestConfiguration.class)
static class Config {
diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/HsqlDbOnly.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/HsqlDbOnly.java
new file mode 100644
index 0000000000..4990b6d148
--- /dev/null
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/HsqlDbOnly.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.jdbc.testing;
+
+import org.springframework.test.annotation.IfProfileValue;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Run the annotated test only against a HsqlDb database.
+ *
+ * Requires the use of {@code @ProfileValueSourceConfiguration(DatabaseProfileValueSource.class)} on the test.
+ *
+ * @author Jens Schauder
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@IfProfileValue(name = "current.database.is.not.hsqldb", value = "false")
+public @interface HsqlDbOnly {
+}
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql
index bd14282b3e..02071e25c8 100644
--- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql
@@ -292,4 +292,10 @@ CREATE TABLE NO_ID_MAP_CHAIN0
NO_ID_MAP_CHAIN3_KEY,
NO_ID_MAP_CHAIN2_KEY
)
-);
\ No newline at end of file
+);
+
+CREATE TABLE WITH_READ_ONLY (
+ ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 40) PRIMARY KEY,
+ NAME VARCHAR(200),
+ READ_ONLY VARCHAR(200) DEFAULT 'from-db'
+)
\ No newline at end of file
diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml
index 1751c4244e..24956f2581 100644
--- a/spring-data-relational/pom.xml
+++ b/spring-data-relational/pom.xml
@@ -5,7 +5,7 @@
4.0.0
spring-data-relational
- 1.2.0.BUILD-SNAPSHOT
+ 1.2.0.DATAJDBC-431-SNAPSHOT
Spring Data Relational
Spring Data Relational support
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-relational-parent
- 1.2.0.BUILD-SNAPSHOT
+ 1.2.0.DATAJDBC-431-SNAPSHOT