Support inserts for id only entities.

This broke in the past for some databases that do not support empty value lists.

Closes #777
Original pull request #1047
This commit is contained in:
Mikhail-Polivakha
2021-09-14 17:11:25 +03:00
committed by Jens Schauder
parent a2a5953cda
commit 7551cbd763
23 changed files with 263 additions and 62 deletions

View File

@@ -50,6 +50,7 @@ import java.util.stream.Collectors;
* @author Tyler Van Gorder
* @author Milan Milanov
* @author Myeonghyeon Lee
* @author Mikhail Polivakha
*/
class SqlGenerator {
@@ -92,12 +93,14 @@ 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(new RenderContextFactory(dialect).createRenderContext());
this.sqlRenderer = SqlRenderer.create(renderContextFactory.createRenderContext());
this.columns = new Columns(entity, mappingContext, converter);
this.renderContext = new RenderContextFactory(dialect).createRenderContext();
this.renderContext = renderContextFactory.createRenderContext();
}
/**

View File

@@ -80,6 +80,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Tyler Van Gorder
* @author Clemens Hahn
* @author Milan Milanov
* @author Mikhail Polivakha
*/
@ContextConfiguration
@Transactional
@@ -887,6 +888,12 @@ public class JdbcAggregateTemplateIntegrationTests {
assertThat(loaded.testTime).isEqualTo(entity.testTime);
}
@Test // DATAJDBC-557
public void insertWithIdOnly() {
WithIdOnly entity = new WithIdOnly();
assertThat(template.save(entity).id).isNotNull();
}
private <T extends Number> void saveAndUpdateAggregateWithVersion(VersionedAggregate aggregate,
Function<Number, T> toConcreteNumber) {
saveAndUpdateAggregateWithVersion(aggregate, toConcreteNumber, 0);
@@ -1254,6 +1261,11 @@ public class JdbcAggregateTemplateIntegrationTests {
LocalDateTime testTime;
}
@Table
class WithIdOnly {
@Id Long id;
}
@Configuration
@Import(TestConfiguration.class)
static class Config {

View File

@@ -39,6 +39,8 @@ import org.springframework.data.jdbc.core.mapping.PersistentPropertyPathTestUtil
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.dialect.AnsiDialect;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.dialect.PostgresDialect;
import org.springframework.data.relational.core.dialect.SqlServerDialect;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.NamingStrategy;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
@@ -61,6 +63,7 @@ import org.springframework.data.relational.core.sql.Table;
* @author Tom Hombergs
* @author Milan Milanov
* @author Myeonghyeon Lee
* @author Mikhail Polivakha
*/
class SqlGeneratorUnitTests {
@@ -391,13 +394,22 @@ class SqlGeneratorUnitTests {
}
@Test // DATAJDBC-264
void getInsertForEmptyColumnList() {
void getInsertForEmptyColumnListPostgres() {
SqlGenerator sqlGenerator = createSqlGenerator(IdOnlyEntity.class);
SqlGenerator sqlGenerator = createSqlGenerator(IdOnlyEntity.class, PostgresDialect.INSTANCE);
String insert = sqlGenerator.getInsert(emptySet());
String insertSqlStatement = sqlGenerator.getInsert(emptySet());
assertThat(insert).endsWith("()");
assertThat(insertSqlStatement).endsWith(" VALUES (DEFAULT) ");
}
@Test //DATAJDBC-557
void gerInsertForEmptyColumnListMsSqlServer() {
SqlGenerator sqlGenerator = createSqlGenerator(IdOnlyEntity.class, SqlServerDialect.INSTANCE);
String insertSqlStatement = sqlGenerator.getInsert(emptySet());
assertThat(insertSqlStatement).endsWith(" DEFAULT VALUES ");
}
@Test // DATAJDBC-334

View File

@@ -37,6 +37,8 @@ DROP TABLE WITH_READ_ONLY;
DROP TABLE VERSIONED_AGGREGATE;
DROP TABLE WITH_LOCAL_DATE_TIME;
DROP TABLE WITH_ID_ONLY;
CREATE TABLE LEGO_SET
(
"id1" BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
@@ -350,4 +352,9 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
(
ID BIGINT NOT NULL PRIMARY KEY,
TEST_TIME TIMESTAMP(9)
);
CREATE TABLE WITH_ID_ONLY
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY
);

View File

@@ -321,4 +321,9 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
(
ID BIGINT PRIMARY KEY,
TEST_TIME TIMESTAMP(9) WITHOUT TIME ZONE
);
CREATE TABLE WITH_ID_ONLY
(
ID SERIAL PRIMARY KEY
);

View File

@@ -323,4 +323,9 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
(
ID BIGINT PRIMARY KEY,
TEST_TIME TIMESTAMP(9)
);
);
CREATE TABLE WITH_ID_ONLY
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY
)

View File

@@ -296,4 +296,9 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
(
ID BIGINT PRIMARY KEY,
TEST_TIME TIMESTAMP(6)
);
CREATE TABLE WITH_ID_ONLY
(
ID BIGINT AUTO_INCREMENT PRIMARY KEY
);

View File

@@ -324,4 +324,11 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
(
ID BIGINT PRIMARY KEY,
TEST_TIME datetime2(7)
);
DROP TABLE IF EXISTS WITH_ID_ONLY;
CREATE TABLE WITH_ID_ONLY
(
ID BIGINT IDENTITY PRIMARY KEY
);

View File

@@ -301,4 +301,9 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
(
ID BIGINT PRIMARY KEY,
TEST_TIME TIMESTAMP(6)
);
CREATE TABLE WITH_ID_ONLY
(
ID BIGINT AUTO_INCREMENT PRIMARY KEY
);

View File

@@ -28,6 +28,7 @@ DROP TABLE NO_ID_MAP_CHAIN4 CASCADE CONSTRAINTS PURGE;
DROP TABLE VERSIONED_AGGREGATE CASCADE CONSTRAINTS PURGE;
DROP TABLE WITH_READ_ONLY CASCADE CONSTRAINTS PURGE;
DROP TABLE WITH_LOCAL_DATE_TIME CASCADE CONSTRAINTS PURGE;
DROP TABLE WITH_ID_ONLY CASCADE CONSTRAINTS PURGE;
CREATE TABLE LEGO_SET
(
@@ -332,4 +333,9 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
(
ID NUMBER PRIMARY KEY,
TEST_TIME TIMESTAMP(9)
);
CREATE TABLE WITH_ID_ONLY
(
ID NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY
);

View File

@@ -12,6 +12,7 @@ DROP TABLE CHAIN2;
DROP TABLE CHAIN1;
DROP TABLE CHAIN0;
DROP TABLE WITH_READ_ONLY;
DROP TABLE WITH_ID_ONLY;
CREATE TABLE LEGO_SET
(
@@ -335,4 +336,9 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
(
ID BIGINT PRIMARY KEY,
TEST_TIME TIMESTAMP(9) WITHOUT TIME ZONE
);
CREATE TABLE WITH_ID_ONLY
(
ID SERIAL PRIMARY KEY
);