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 5ecca365..80fa379a 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
@@ -93,14 +93,12 @@ class SqlGenerator {
SqlGenerator(RelationalMappingContext mappingContext, JdbcConverter converter, RelationalPersistentEntity> entity,
Dialect dialect) {
- final RenderContextFactory renderContextFactory = new RenderContextFactory(dialect);
-
this.mappingContext = mappingContext;
this.entity = entity;
this.sqlContext = new SqlContext(entity);
- this.sqlRenderer = SqlRenderer.create(renderContextFactory.createRenderContext());
+ this.renderContext = new RenderContextFactory(dialect).createRenderContext();
+ this.sqlRenderer = SqlRenderer.create(renderContext);
this.columns = new Columns(entity, mappingContext, converter);
- this.renderContext = renderContextFactory.createRenderContext();
}
/**
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 c7c339c7..7c3f0c4f 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
@@ -888,9 +888,11 @@ public class JdbcAggregateTemplateIntegrationTests {
assertThat(loaded.testTime).isEqualTo(entity.testTime);
}
- @Test // DATAJDBC-557
+ @Test // GH-777
public void insertWithIdOnly() {
+
WithIdOnly entity = new WithIdOnly();
+
assertThat(template.save(entity).id).isNotNull();
}
diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java
index 48464a0f..5098823c 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java
@@ -219,7 +219,7 @@ public class DefaultDataAccessStrategyUnitTests {
assertThat(generatedId).isEqualTo(GENERATED_ID);
- verify(namedJdbcOperations).update(eq("INSERT INTO \"DUMMY_ENTITY\" VALUES ()"),
+ verify(namedJdbcOperations).update(eq("INSERT INTO \"DUMMY_ENTITY\" VALUES (DEFAULT)"),
paramSourceCaptor.capture(), any(KeyHolder.class));
}
diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java
index 5b0fa054..363d9c9d 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java
@@ -398,18 +398,19 @@ class SqlGeneratorUnitTests {
SqlGenerator sqlGenerator = createSqlGenerator(IdOnlyEntity.class, PostgresDialect.INSTANCE);
- String insertSqlStatement = sqlGenerator.getInsert(emptySet());
+ String insert = sqlGenerator.getInsert(emptySet());
- assertThat(insertSqlStatement).endsWith(" VALUES (DEFAULT) ");
+ assertThat(insert).endsWith(" VALUES (DEFAULT)");
}
- @Test //DATAJDBC-557
+ @Test // GH-777
void gerInsertForEmptyColumnListMsSqlServer() {
+
SqlGenerator sqlGenerator = createSqlGenerator(IdOnlyEntity.class, SqlServerDialect.INSTANCE);
- String insertSqlStatement = sqlGenerator.getInsert(emptySet());
+ String insert = sqlGenerator.getInsert(emptySet());
- assertThat(insertSqlStatement).endsWith(" DEFAULT VALUES ");
+ assertThat(insert).endsWith(" DEFAULT VALUES");
}
@Test // DATAJDBC-334
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java
index c66fe997..5febb8c5 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java
@@ -112,11 +112,12 @@ public interface Dialect {
}
/**
- * @return an appropriate {@link InsertWithDefaultValues } for that specific dialect.
+ * @return an appropriate {@link InsertRenderContext} for that specific dialect.
* for most of the Dialects the default implementation will be valid, but, for
- * example, in case of {@link SqlServerDialect} it is not
+ * example, in case of {@link SqlServerDialect} it is not.
+ * @since 2.4
*/
- default InsertWithDefaultValues getSqlInsertWithDefaultValues() {
- return new InsertWithDefaultValues() {};
+ default InsertRenderContext getInsertRenderContext() {
+ return InsertRenderContexts.DEFAULT;
}
}
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertRenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertRenderContext.java
new file mode 100644
index 00000000..e02c3934
--- /dev/null
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertRenderContext.java
@@ -0,0 +1,16 @@
+package org.springframework.data.relational.core.dialect;
+
+import org.springframework.data.relational.core.sql.Insert;
+import org.springframework.data.relational.core.sql.render.RenderContext;
+
+/**
+ * This interface encapsulates the details about how to process {@link Insert} SQL statement
+ *
+ * @see RenderContext
+ * @author Mikhail Polivakha
+ * @since 2.4
+ */
+public interface InsertRenderContext {
+
+ String getDefaultValuesInsertPart();
+}
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertRenderContexts.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertRenderContexts.java
new file mode 100644
index 00000000..352a7502
--- /dev/null
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertRenderContexts.java
@@ -0,0 +1,25 @@
+package org.springframework.data.relational.core.dialect;
+
+/**
+ * In the scope of Insert with default values SQL statement, for example {@literal INSERT INTO SCHEMA.TABLE VALUES
+ * (DEFAULT)} this enum represents the default values part in different {@link Dialect}s
+ *
+ * @author Mikhail Polivakha
+ * @since 2.4
+ */
+public enum InsertRenderContexts implements InsertRenderContext {
+
+ DEFAULT(" VALUES (DEFAULT)"), //
+ MS_SQL_SERVER(" DEFAULT VALUES");
+
+ private final String defaultInsertPart;
+
+ InsertRenderContexts(String defaultInsertPart) {
+ this.defaultInsertPart = defaultInsertPart;
+ }
+
+ public String getDefaultValuesInsertPart() {
+ return defaultInsertPart;
+ }
+
+}
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertWithDefaultValues.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertWithDefaultValues.java
index 4710ab79..20045086 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertWithDefaultValues.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/InsertWithDefaultValues.java
@@ -1,17 +1,15 @@
package org.springframework.data.relational.core.dialect;
-import org.springframework.data.relational.core.mapping.InsertDefaultValues;
-
/**
* This interface aggregates information about an Insert with default values statement.
+ *
* @author Mikhail Polivakha
+ * @since 2.4
*/
public interface InsertWithDefaultValues {
- /**
- * @return the part of the sql statement, that follows after INSERT INTO table
- */
- default String getDefaultInsertPart() {
- return InsertDefaultValues.DEFAULT.getDefaultInsertPart();
- }
-}
\ No newline at end of file
+ /**
+ * @return the part of the sql statement, that follows after INSERT INTO table
+ */
+ String getDefaultInsertPart();
+}
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/RenderContextFactory.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/RenderContextFactory.java
index b35014a5..c9dcc065 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/RenderContextFactory.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/RenderContextFactory.java
@@ -16,7 +16,6 @@
package org.springframework.data.relational.core.dialect;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
-import org.springframework.data.relational.core.sql.render.InsertRenderContext;
import org.springframework.data.relational.core.sql.render.NamingStrategies;
import org.springframework.data.relational.core.sql.render.RenderContext;
import org.springframework.data.relational.core.sql.render.RenderNamingStrategy;
@@ -78,19 +77,23 @@ public class RenderContextFactory {
static class DialectRenderContext implements RenderContext {
private final RenderNamingStrategy renderNamingStrategy;
- private final SelectRenderContext selectRenderContext;
private final Dialect renderingDialect;
+ private final SelectRenderContext selectRenderContext;
+ private final InsertRenderContext insertRenderContext;
- DialectRenderContext(RenderNamingStrategy renderNamingStrategy, Dialect renderingDialect, SelectRenderContext selectRenderContext) {
+ DialectRenderContext(RenderNamingStrategy renderNamingStrategy, Dialect renderingDialect,
+ SelectRenderContext selectRenderContext) {
Assert.notNull(renderNamingStrategy, "RenderNamingStrategy must not be null");
Assert.notNull(renderingDialect, "renderingDialect must not be null");
- Assert.notNull(renderingDialect.getIdentifierProcessing(), "IdentifierProcessing of renderingDialect must not be null");
+ Assert.notNull(renderingDialect.getIdentifierProcessing(),
+ "IdentifierProcessing of renderingDialect must not be null");
Assert.notNull(selectRenderContext, "SelectRenderContext must not be null");
this.renderNamingStrategy = renderNamingStrategy;
this.renderingDialect = renderingDialect;
this.selectRenderContext = selectRenderContext;
+ this.insertRenderContext = renderingDialect.getInsertRenderContext();
}
/*
@@ -111,6 +114,11 @@ public class RenderContextFactory {
return renderingDialect.getIdentifierProcessing();
}
+ @Override
+ public SelectRenderContext getSelect() {
+ return getSelectRenderContext();
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.relational.core.sql.render.RenderContext#getSelect()
@@ -122,12 +130,7 @@ public class RenderContextFactory {
@Override
public InsertRenderContext getInsertRenderContext() {
- return new InsertRenderContext() {
- @Override
- public String getInsertDefaultValuesPartSQL() {
- return renderingDialect.getSqlInsertWithDefaultValues().getDefaultInsertPart();
- }
- };
+ return insertRenderContext;
}
}
-}
\ No newline at end of file
+}
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java
index cf3bcbbc..11ae0d3c 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java
@@ -15,7 +15,6 @@
*/
package org.springframework.data.relational.core.dialect;
-import org.springframework.data.relational.core.mapping.InsertDefaultValues;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
import org.springframework.data.relational.core.sql.LockOptions;
import org.springframework.data.relational.core.sql.render.SelectRenderContext;
@@ -154,12 +153,7 @@ public class SqlServerDialect extends AbstractDialect {
}
@Override
- public InsertWithDefaultValues getSqlInsertWithDefaultValues() {
- return new InsertWithDefaultValues() {
- @Override
- public String getDefaultInsertPart() {
- return InsertDefaultValues.MS_SQL_SERVER.getDefaultInsertPart();
- }
- };
+ public InsertRenderContext getInsertRenderContext() {
+ return InsertRenderContexts.MS_SQL_SERVER;
}
}
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/InsertDefaultValues.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/InsertDefaultValues.java
deleted file mode 100644
index 8a9299ed..00000000
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/InsertDefaultValues.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.springframework.data.relational.core.mapping;
-
-import org.springframework.data.relational.core.dialect.Dialect;
-import org.springframework.data.relational.core.dialect.InsertWithDefaultValues;
-
-/**
- * In the scope of Insert with default values SQL statement, for example
- * INSERT INTO SCHEMA.TABLE VALUES (DEFAULT)
- * this enum represents the default values part in different {@link Dialect}s
- *
- * @author Mikhail Polivakha
- * @see InsertWithDefaultValues
- */
-public enum InsertDefaultValues {
-
- DEFAULT(" VALUES (DEFAULT) "),
- MS_SQL_SERVER(" DEFAULT VALUES ");
-
- private final String defaultInsertPart;
-
- InsertDefaultValues(String defaultInsertPart) {
- this.defaultInsertPart = defaultInsertPart;
- }
-
- public String getDefaultInsertPart() {
- return defaultInsertPart;
- }
-}
\ No newline at end of file
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertRenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertRenderContext.java
deleted file mode 100644
index 6824d8c7..00000000
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertRenderContext.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.springframework.data.relational.core.sql.render;
-
-import org.springframework.data.relational.core.mapping.InsertDefaultValues;
-import org.springframework.data.relational.core.sql.Insert;
-
-/**
- * This interface encapsulates the details about how to
- * process {@link Insert} SQL statement
- *
- * @see RenderContext
- * @author Mikhail Polivakha
- */
-public interface InsertRenderContext {
-
- default String getInsertDefaultValuesPartSQL() {
- return InsertDefaultValues.DEFAULT.getDefaultInsertPart();
- }
-}
\ No newline at end of file
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertStatementVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertStatementVisitor.java
index 75cf4407..472914c5 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertStatementVisitor.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertStatementVisitor.java
@@ -15,7 +15,6 @@
*/
package org.springframework.data.relational.core.sql.render;
-import org.jetbrains.annotations.NotNull;
import org.springframework.data.relational.core.sql.Column;
import org.springframework.data.relational.core.sql.Insert;
import org.springframework.data.relational.core.sql.Into;
@@ -98,24 +97,6 @@ class InsertStatementVisitor extends DelegatingVisitor implements PartRenderer {
return Delegation.retain();
}
- private void addInsertValuesIfPresentElseDefault() {
- if (values.length() != 0) {
- builder.append(" VALUES (").append(values).append(")");
- } else {
- addInsertWithDefaultValuesToBuilder();
- }
- }
-
- private void addInsertColumnsIfPresent() {
- if (columns.length() != 0) {
- builder.append(" (").append(columns).append(")");
- }
- }
-
- private void addInsertWithDefaultValuesToBuilder() {
- builder.append(renderContext.getInsertRenderContext().getInsertDefaultValuesPartSQL());
- }
-
/*
* (non-Javadoc)
* @see org.springframework.data.relational.core.sql.render.PartRenderer#getRenderedPart()
@@ -125,8 +106,28 @@ class InsertStatementVisitor extends DelegatingVisitor implements PartRenderer {
return builder;
}
- @NotNull
+ private void addInsertValuesIfPresentElseDefault() {
+
+ if (values.length() != 0) {
+ builder.append(" VALUES (").append(values).append(")");
+ } else {
+ addInsertWithDefaultValuesToBuilder();
+ }
+ }
+
+ private void addInsertColumnsIfPresent() {
+
+ if (columns.length() != 0) {
+ builder.append(" (").append(columns).append(")");
+ }
+ }
+
+ private void addInsertWithDefaultValuesToBuilder() {
+ builder.append(renderContext.getInsertRenderContext().getDefaultValuesInsertPart());
+ }
+
private ColumnVisitor createColumnVisitor(RenderContext context) {
+
return new ColumnVisitor(context, false, it -> {
if (columns.length() != 0) {
@@ -137,8 +138,8 @@ class InsertStatementVisitor extends DelegatingVisitor implements PartRenderer {
});
}
- @NotNull
private IntoClauseVisitor createIntoClauseVisitor(RenderContext context) {
+
return new IntoClauseVisitor(context, it -> {
if (into.length() != 0) {
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderContext.java
index 2d40ef51..38a1c210 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderContext.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderContext.java
@@ -15,6 +15,7 @@
*/
package org.springframework.data.relational.core.sql.render;
+import org.springframework.data.relational.core.dialect.InsertRenderContext;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
/**
@@ -43,8 +44,17 @@ public interface RenderContext {
/**
* @return the {@link SelectRenderContext}.
+ * @deprecated Use {@link #getInsertRenderContext()} instead.
*/
- SelectRenderContext getSelectRenderContext();
+ @Deprecated
+ SelectRenderContext getSelect();
+
+ /**
+ * @return the {@link SelectRenderContext}.
+ */
+ default SelectRenderContext getSelectRenderContext() {
+ return getSelect();
+ }
/**
* @return the {@link InsertRenderContext}
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleRenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleRenderContext.java
index 3886d5c4..552067a4 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleRenderContext.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleRenderContext.java
@@ -15,6 +15,8 @@
*/
package org.springframework.data.relational.core.sql.render;
+import org.springframework.data.relational.core.dialect.InsertRenderContext;
+import org.springframework.data.relational.core.dialect.InsertRenderContexts;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
/**
@@ -36,6 +38,11 @@ final class SimpleRenderContext implements RenderContext {
return IdentifierProcessing.NONE;
}
+ @Override
+ public SelectRenderContext getSelect() {
+ return getSelectRenderContext();
+ }
+
@Override
public SelectRenderContext getSelectRenderContext() {
return DefaultSelectRenderContext.INSTANCE;
@@ -43,7 +50,7 @@ final class SimpleRenderContext implements RenderContext {
@Override
public InsertRenderContext getInsertRenderContext() {
- return new InsertRenderContext() {};
+ return InsertRenderContexts.DEFAULT;
}
public RenderNamingStrategy getNamingStrategy() {
diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SqlRenderer.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SqlRenderer.java
index 9c93fe68..93999346 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SqlRenderer.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SqlRenderer.java
@@ -69,6 +69,16 @@ public class SqlRenderer implements Renderer {
return create().render(select);
}
+ /**
+ * Renders a {@link Insert} statement into its SQL representation.
+ *
+ * @param insert must not be {@literal null}.
+ * @return the rendered statement.
+ */
+ public static String toString(Insert insert) {
+ return create().render(insert);
+ }
+
/**
* Renders a {@link Update} statement into its SQL representation.
*