Support for ID generation by sequence.

Ids can be annotated with @Sequence to specify a sequence to pull id values from.

Closes #1923
Original pull request #1955

Signed-off-by: mipo256 <mikhailpolivakha@gmail.com>

Some accidential changes removed.
Signed-off-by: schauder <jens.schauder@broadcom.com>
This commit is contained in:
Mikhail2048
2024-10-26 13:04:22 +03:00
committed by Jens Schauder
parent b51c77b50a
commit d1c996008c
33 changed files with 716 additions and 39 deletions

View File

@@ -118,8 +118,13 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
Assert.notEmpty(insertSubjects, "Batch insert must contain at least one InsertSubject");
SqlIdentifierParameterSource[] sqlParameterSources = insertSubjects.stream()
.map(insertSubject -> sqlParametersFactory.forInsert(insertSubject.getInstance(), domainType,
insertSubject.getIdentifier(), idValueSource))
.map(insertSubject -> sqlParametersFactory.forInsert( //
insertSubject.getInstance(), //
domainType, //
insertSubject.getIdentifier(), //
idValueSource //
) //
) //
.toArray(SqlIdentifierParameterSource[]::new);
String insertSql = sql(domainType).getInsert(sqlParameterSources[0].getIdentifiers());
@@ -280,7 +285,8 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
@Override
public <T> Stream<T> streamAll(Class<T> domainType) {
return operations.queryForStream(sql(domainType).getFindAll(), new MapSqlParameterSource(), getEntityRowMapper(domainType));
return operations.queryForStream(sql(domainType).getFindAll(), new MapSqlParameterSource(),
getEntityRowMapper(domainType));
}
@Override
@@ -364,7 +370,8 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
@Override
public <T> Stream<T> streamAll(Class<T> domainType, Sort sort) {
return operations.queryForStream(sql(domainType).getFindAll(sort), new MapSqlParameterSource(), getEntityRowMapper(domainType));
return operations.queryForStream(sql(domainType).getFindAll(sort), new MapSqlParameterSource(),
getEntityRowMapper(domainType));
}
@Override
@@ -479,5 +486,4 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
return baseProperty.getOwner().getType();
}
}

View File

@@ -0,0 +1,71 @@
package org.springframework.data.jdbc.core.mapping;
import java.util.Map;
import java.util.Optional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.relational.core.conversion.MutableAggregateChange;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.event.BeforeSaveCallback;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.util.Assert;
/**
* Callback for generating ID via the database sequence. By default, it is registered as a
* bean in {@link AbstractJdbcConfiguration}
*
* @author Mikhail Polivakha
*/
public class IdGeneratingBeforeSaveCallback implements BeforeSaveCallback<Object> {
private static final Log LOG = LogFactory.getLog(IdGeneratingBeforeSaveCallback.class);
private final RelationalMappingContext relationalMappingContext;
private final Dialect dialect;
private final NamedParameterJdbcOperations operations;
public IdGeneratingBeforeSaveCallback(
RelationalMappingContext relationalMappingContext,
Dialect dialect,
NamedParameterJdbcOperations namedParameterJdbcOperations
) {
this.relationalMappingContext = relationalMappingContext;
this.dialect = dialect;
this.operations = namedParameterJdbcOperations;
}
@Override
public Object onBeforeSave(Object aggregate, MutableAggregateChange<Object> aggregateChange) {
Assert.notNull(aggregate, "The aggregate cannot be null at this point");
RelationalPersistentEntity<?> persistentEntity = relationalMappingContext.getPersistentEntity(aggregate.getClass());
Optional<String> idTargetSequence = persistentEntity.getIdTargetSequence();
if (dialect.getIdGeneration().sequencesSupported()) {
if (persistentEntity.getIdProperty() != null) {
idTargetSequence
.map(s -> dialect.getIdGeneration().nextValueFromSequenceSelect(s))
.ifPresent(sql -> {
Long idValue = operations.queryForObject(sql, Map.of(), (rs, rowNum) -> rs.getLong(1));
PersistentPropertyAccessor<Object> propertyAccessor = persistentEntity.getPropertyAccessor(aggregate);
propertyAccessor.setProperty(persistentEntity.getRequiredIdProperty(), idValue);
});
}
} else {
if (idTargetSequence.isPresent()) {
LOG.warn("""
It seems you're trying to insert an aggregate of type '%s' annotated with @TargetSequence, but the problem is RDBMS you're
working with does not support sequences as such. Falling back to identity columns
"""
.formatted(aggregate.getClass().getName())
);
}
}
return aggregate;
}
}

View File

@@ -38,6 +38,7 @@ import org.springframework.data.jdbc.core.JdbcAggregateOperations;
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
import org.springframework.data.jdbc.core.convert.*;
import org.springframework.data.jdbc.core.dialect.JdbcDialect;
import org.springframework.data.jdbc.core.mapping.IdGeneratingBeforeSaveCallback;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
import org.springframework.data.mapping.model.SimpleTypeHolder;
@@ -119,6 +120,22 @@ public class AbstractJdbcConfiguration implements ApplicationContextAware {
return mappingContext;
}
/**
* Creates a {@link IdGeneratingBeforeSaveCallback} bean using the configured
* {@link #jdbcMappingContext(Optional, JdbcCustomConversions, RelationalManagedTypes)} and
* {@link #jdbcDialect(NamedParameterJdbcOperations)}.
*
* @return must not be {@literal null}.
*/
@Bean
public IdGeneratingBeforeSaveCallback idGeneratingBeforeSaveCallback(
JdbcMappingContext mappingContext,
NamedParameterJdbcOperations operations,
Dialect dialect
) {
return new IdGeneratingBeforeSaveCallback(mappingContext, dialect, operations);
}
/**
* Creates a {@link RelationalConverter} using the configured
* {@link #jdbcMappingContext(Optional, JdbcCustomConversions, RelationalManagedTypes)}.

View File

@@ -33,7 +33,6 @@ import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.relational.core.conversion.IdValueSource;
import org.springframework.data.relational.core.dialect.AnsiDialect;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.sql.SqlIdentifier;
@@ -49,7 +48,6 @@ class SqlParametersFactoryTest {
RelationalMappingContext context = new JdbcMappingContext();
RelationResolver relationResolver = mock(RelationResolver.class);
MappingJdbcConverter converter = new MappingJdbcConverter(context, relationResolver);
AnsiDialect dialect = AnsiDialect.INSTANCE;
SqlParametersFactory sqlParametersFactory = new SqlParametersFactory(context, converter);
@Test // DATAJDBC-412

View File

@@ -0,0 +1,121 @@
package org.springframework.data.jdbc.core.mapping;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.conversion.MutableAggregateChange;
import org.springframework.data.relational.core.dialect.MySqlDialect;
import org.springframework.data.relational.core.dialect.PostgresDialect;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.relational.core.mapping.TargetSequence;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
/**
* Unit tests for {@link IdGeneratingBeforeSaveCallback}
*
* @author Mikhail Polivakha
*/
class IdGeneratingBeforeSaveCallbackTest {
@Test
void test_mySqlDialect_sequenceGenerationIsNotSupported() {
// given
RelationalMappingContext relationalMappingContext = new RelationalMappingContext();
MySqlDialect mySqlDialect = new MySqlDialect(IdentifierProcessing.NONE);
NamedParameterJdbcOperations operations = mock(NamedParameterJdbcOperations.class);
// and
IdGeneratingBeforeSaveCallback subject = new IdGeneratingBeforeSaveCallback(relationalMappingContext, mySqlDialect, operations);
NoSequenceEntity entity = new NoSequenceEntity();
// when
Object processed = subject.onBeforeSave(entity, MutableAggregateChange.forSave(entity));
// then
Assertions.assertThat(processed).isSameAs(entity);
Assertions.assertThat(processed).usingRecursiveComparison().isEqualTo(entity);
}
@Test
void test_EntityIsNotMarkedWithTargetSequence() {
// given
RelationalMappingContext relationalMappingContext = new RelationalMappingContext();
PostgresDialect mySqlDialect = PostgresDialect.INSTANCE;
NamedParameterJdbcOperations operations = mock(NamedParameterJdbcOperations.class);
// and
IdGeneratingBeforeSaveCallback subject = new IdGeneratingBeforeSaveCallback(relationalMappingContext, mySqlDialect, operations);
NoSequenceEntity entity = new NoSequenceEntity();
// when
Object processed = subject.onBeforeSave(entity, MutableAggregateChange.forSave(entity));
// then
Assertions.assertThat(processed).isSameAs(entity);
Assertions.assertThat(processed).usingRecursiveComparison().isEqualTo(entity);
}
@Test
void test_EntityIdIsPopulatedFromSequence() {
// given
RelationalMappingContext relationalMappingContext = new RelationalMappingContext();
relationalMappingContext.getRequiredPersistentEntity(EntityWithSequence.class);
PostgresDialect mySqlDialect = PostgresDialect.INSTANCE;
NamedParameterJdbcOperations operations = mock(NamedParameterJdbcOperations.class);
// and
long generatedId = 112L;
when(operations.queryForObject(anyString(), anyMap(), any(RowMapper.class))).thenReturn(generatedId);
// and
IdGeneratingBeforeSaveCallback subject = new IdGeneratingBeforeSaveCallback(relationalMappingContext, mySqlDialect, operations);
EntityWithSequence entity = new EntityWithSequence();
// when
Object processed = subject.onBeforeSave(entity, MutableAggregateChange.forSave(entity));
// then
Assertions.assertThat(processed).isSameAs(entity);
Assertions
.assertThat(processed)
.usingRecursiveComparison()
.ignoringFields("id")
.isEqualTo(entity);
Assertions.assertThat(entity.getId()).isEqualTo(generatedId);
}
@Table
static class NoSequenceEntity {
@Id
private Long id;
private Long name;
}
@Table
static class EntityWithSequence {
@Id
@TargetSequence(value = "id_seq", schema = "public")
private Long id;
private Long name;
public Long getId() {
return id;
}
}
}

View File

@@ -42,7 +42,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.ApplicationListener;
@@ -52,16 +51,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.core.io.ClassPathResource;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Limit;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.ScrollPosition;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Window;
import org.springframework.data.domain.*;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.jdbc.repository.query.Modifying;
import org.springframework.data.jdbc.repository.query.Query;
@@ -75,6 +65,7 @@ import org.springframework.data.jdbc.testing.TestDatabaseFeatures;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.MappedCollection;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.relational.core.mapping.TargetSequence;
import org.springframework.data.relational.core.mapping.event.AbstractRelationalEvent;
import org.springframework.data.relational.core.mapping.event.AfterConvertEvent;
import org.springframework.data.relational.core.sql.LockMode;
@@ -115,8 +106,8 @@ public class JdbcRepositoryIntegrationTests {
@Autowired DummyEntityRepository repository;
@Autowired MyEventListener eventListener;
@Autowired RootRepository rootRepository;
@Autowired WithDelimitedColumnRepository withDelimitedColumnRepository;
@Autowired EntityWithSequenceRepository entityWithSequenceRepository;
@BeforeEach
public void before() {
@@ -135,6 +126,28 @@ public class JdbcRepositoryIntegrationTests {
"id_Prop = " + entity.getIdProp())).isEqualTo(1);
}
@Test
@EnabledOnFeature(value = TestDatabaseFeatures.Feature.SUPPORTS_SEQUENCES)
public void saveEntityWithTargetSequenceSpecified() {
EntityWithSequence first = entityWithSequenceRepository.save(new EntityWithSequence("first"));
EntityWithSequence second = entityWithSequenceRepository.save(new EntityWithSequence("second"));
assertThat(first.getId()).isNotNull();
assertThat(second.getId()).isNotNull();
assertThat(first.getId()).isLessThan(second.getId());
assertThat(first.getName()).isEqualTo("first");
assertThat(second.getName()).isEqualTo("second");
}
@Test
@EnabledOnFeature(value = TestDatabaseFeatures.Feature.SUPPORTS_SEQUENCES)
public void batchInsertEntityWithTargetSequenceSpecified() {
Iterable<EntityWithSequence> results = entityWithSequenceRepository
.saveAll(List.of(new EntityWithSequence("first"), new EntityWithSequence("second")));
assertThat(results).hasSize(2).extracting(EntityWithSequence::getId).containsExactly(1L, 2L);
}
@Test // DATAJDBC-95
public void saveAndLoadAnEntity() {
@@ -1515,6 +1528,8 @@ public class JdbcRepositoryIntegrationTests {
interface WithDelimitedColumnRepository extends CrudRepository<WithDelimitedColumn, Long> {}
interface EntityWithSequenceRepository extends CrudRepository<EntityWithSequence, Long> {}
@Configuration
@Import(TestConfiguration.class)
static class Config {
@@ -1536,6 +1551,11 @@ public class JdbcRepositoryIntegrationTests {
return factory.getRepository(WithDelimitedColumnRepository.class);
}
@Bean
EntityWithSequenceRepository entityWithSequenceRepository() {
return factory.getRepository(EntityWithSequenceRepository.class);
}
@Bean
NamedQueries namedQueries() throws IOException {
@@ -1839,6 +1859,31 @@ public class JdbcRepositoryIntegrationTests {
return entity;
}
static class EntityWithSequence {
@Id
@TargetSequence(sequence = "entity_sequence") private Long id;
private String name;
public EntityWithSequence(Long id, String name) {
this.id = id;
this.name = name;
}
public EntityWithSequence(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
static class DummyEntity {
String name;

View File

@@ -0,0 +1,27 @@
package org.springframework.data.jdbc.testing;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.EnabledIf;
/**
* Annotation that allows to disable a particular test to be executed on a particular database
*
* @author Mikhail Polivakha
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ExtendWith(DisabledOnDatabaseExecutionCondition.class)
public @interface DisabledOnDatabase {
/**
* The database on which the test is not supposed to run on
*/
DatabaseType database();
}

View File

@@ -0,0 +1,36 @@
package org.springframework.data.jdbc.testing;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* {@link ExecutionCondition} for the {@link DisabledOnDatabase} annotation
*
* @author Mikhail Polivakha
*/
public class DisabledOnDatabaseExecutionCondition implements ExecutionCondition {
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
ApplicationContext applicationContext = SpringExtension.getApplicationContext(context);
MergedAnnotation<DisabledOnDatabase> disabledOnDatabaseMergedAnnotation = MergedAnnotations
.from(context.getRequiredTestMethod(), MergedAnnotations.SearchStrategy.DIRECT)
.get(DisabledOnDatabase.class);
DatabaseType database = disabledOnDatabaseMergedAnnotation.getEnum("database", DatabaseType.class);
if (ArrayUtils.contains(applicationContext.getEnvironment().getActiveProfiles(), database.getProfile())) {
return ConditionEvaluationResult.disabled(
"The test method '%s' is disabled for '%s' because of the @DisabledOnDatabase annotation".formatted(context.getRequiredTestMethod().getName(), database)
);
}
return ConditionEvaluationResult.enabled("The test method '%s' is enabled".formatted(context.getRequiredTestMethod()));
}
}

View File

@@ -36,11 +36,15 @@ import org.springframework.context.annotation.Profile;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.jdbc.core.convert.*;
import org.springframework.data.jdbc.core.dialect.JdbcDialect;
import org.springframework.data.jdbc.core.mapping.IdGeneratingBeforeSaveCallback;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
import org.springframework.data.jdbc.repository.config.DialectResolver;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.mapping.callback.EntityCallback;
import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.relational.RelationalManagedTypes;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.DefaultNamingStrategy;
import org.springframework.data.relational.core.mapping.NamingStrategy;
@@ -81,10 +85,16 @@ public class TestConfiguration {
JdbcRepositoryFactory jdbcRepositoryFactory(
@Qualifier("defaultDataAccessStrategy") DataAccessStrategy dataAccessStrategy, RelationalMappingContext context,
Dialect dialect, JdbcConverter converter, Optional<List<NamedQueries>> namedQueries,
List<EntityCallback<?>> callbacks,
List<EvaluationContextExtension> evaulationContextExtensions) {
JdbcRepositoryFactory factory = new JdbcRepositoryFactory(dataAccessStrategy, context, converter, dialect,
publisher, namedParameterJdbcTemplate());
factory.setEntityCallbacks(
EntityCallbacks.create(callbacks.toArray(new EntityCallback[0]))
);
namedQueries.map(it -> it.iterator().next()).ifPresent(factory::setNamedQueries);
factory.setEvaluationContextProvider(
@@ -164,6 +174,21 @@ public class TestConfiguration {
new DefaultJdbcTypeFactory(template.getJdbcOperations(), arrayColumns));
}
/**
* Creates a {@link IdGeneratingBeforeSaveCallback} bean using the configured
* {@link #jdbcDialect(NamedParameterJdbcOperations)}.
*
* @return must not be {@literal null}.
*/
@Bean
public IdGeneratingBeforeSaveCallback idGeneratingBeforeSaveCallback(
JdbcMappingContext mappingContext,
NamedParameterJdbcOperations operations,
Dialect dialect
) {
return new IdGeneratingBeforeSaveCallback(mappingContext, dialect, operations);
}
@Bean
Dialect jdbcDialect(NamedParameterJdbcOperations operations) {
return DialectResolver.getDialect(operations.getJdbcOperations());

View File

@@ -30,6 +30,7 @@ import org.springframework.jdbc.core.JdbcOperations;
*
* @author Jens Schauder
* @author Chirag Tailor
* @author Mikhail Polivakha
*/
public class TestDatabaseFeatures {
@@ -79,6 +80,10 @@ public class TestDatabaseFeatures {
assumeThat(database).isNotIn(Database.MySql, Database.MariaDb, Database.SqlServer);
}
private void supportsSequences() {
assumeThat(database).isNotIn(Database.MySql);
}
private void supportsWhereInTuples() {
assumeThat(database).isIn(Database.MySql, Database.PostgreSql);
}
@@ -117,6 +122,7 @@ public class TestDatabaseFeatures {
SUPPORTS_NULL_PRECEDENCE(TestDatabaseFeatures::supportsNullPrecedence),
IS_POSTGRES(f -> f.databaseIs(Database.PostgreSql)), //
WHERE_IN_TUPLE(TestDatabaseFeatures::supportsWhereInTuples), //
SUPPORTS_SEQUENCES(TestDatabaseFeatures::supportsSequences), //
IS_HSQL(f -> f.databaseIs(Database.Hsql));
private final Consumer<TestDatabaseFeatures> featureMethod;

View File

@@ -3,6 +3,8 @@ DROP TABLE ROOT;
DROP TABLE INTERMEDIATE;
DROP TABLE LEAF;
DROP TABLE WITH_DELIMITED_COLUMN;
DROP TABLE ENTITY_WITH_SEQUENCE;
DROP SEQUENCE ENTITY_SEQUENCE;
CREATE TABLE dummy_entity
(
@@ -45,4 +47,12 @@ CREATE TABLE WITH_DELIMITED_COLUMN
ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
"ORG.XTUNIT.IDENTIFIER" VARCHAR(100),
STYPE VARCHAR(100)
);
);
CREATE TABLE ENTITY_WITH_SEQUENCE
(
ID BIGINT,
NAME VARCHAR(100)
);
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

View File

@@ -39,4 +39,12 @@ CREATE TABLE WITH_DELIMITED_COLUMN
ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
"ORG.XTUNIT.IDENTIFIER" VARCHAR(100),
STYPE VARCHAR(100)
);
);
CREATE TABLE ENTITY_WITH_SEQUENCE
(
ID BIGINT,
NAME VARCHAR(100)
);
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

View File

@@ -39,4 +39,12 @@ CREATE TABLE WITH_DELIMITED_COLUMN
ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
"ORG.XTUNIT.IDENTIFIER" VARCHAR(100),
STYPE VARCHAR(100)
);
);
CREATE TABLE ENTITY_WITH_SEQUENCE
(
ID BIGINT,
NAME VARCHAR(100)
);
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

View File

@@ -39,4 +39,12 @@ CREATE TABLE WITH_DELIMITED_COLUMN
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
`ORG.XTUNIT.IDENTIFIER` VARCHAR(100),
STYPE VARCHAR(100)
);
);
CREATE TABLE ENTITY_WITH_SEQUENCE
(
ID BIGINT,
NAME VARCHAR(100)
);
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

View File

@@ -3,6 +3,8 @@ DROP TABLE IF EXISTS ROOT;
DROP TABLE IF EXISTS INTERMEDIATE;
DROP TABLE IF EXISTS LEAF;
DROP TABLE IF EXISTS WITH_DELIMITED_COLUMN;
DROP TABLE IF EXISTS ENTITY_WITH_SEQUENCE;
DROP SEQUENCE IF EXISTS ENTITY_SEQUENCE;
CREATE TABLE dummy_entity
(
@@ -45,4 +47,12 @@ CREATE TABLE WITH_DELIMITED_COLUMN
ID BIGINT IDENTITY PRIMARY KEY,
"ORG.XTUNIT.IDENTIFIER" VARCHAR(100),
STYPE VARCHAR(100)
);
);
CREATE TABLE ENTITY_WITH_SEQUENCE
(
ID BIGINT,
NAME VARCHAR(100)
);
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

View File

@@ -3,6 +3,8 @@ DROP TABLE ROOT CASCADE CONSTRAINTS PURGE;
DROP TABLE INTERMEDIATE CASCADE CONSTRAINTS PURGE;
DROP TABLE LEAF CASCADE CONSTRAINTS PURGE;
DROP TABLE WITH_DELIMITED_COLUMN CASCADE CONSTRAINTS PURGE;
DROP TABLE ENTITY_WITH_SEQUENCE CASCADE CONSTRAINTS PURGE;
DROP SEQUENCE ENTITY_SEQUENCE;
CREATE TABLE DUMMY_ENTITY
(
@@ -46,3 +48,11 @@ CREATE TABLE WITH_DELIMITED_COLUMN
"ORG.XTUNIT.IDENTIFIER" VARCHAR(100),
STYPE VARCHAR(100)
)
CREATE TABLE ENTITY_WITH_SEQUENCE
(
ID BIGINT,
NAME VARCHAR(100)
);
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;

View File

@@ -3,6 +3,8 @@ DROP TABLE ROOT;
DROP TABLE INTERMEDIATE;
DROP TABLE LEAF;
DROP TABLE WITH_DELIMITED_COLUMN;
DROP TABLE ENTITY_WITH_SEQUENCE;
DROP SEQUENCE ENTITY_SEQUENCE;
CREATE TABLE dummy_entity
(
@@ -45,4 +47,12 @@ CREATE TABLE "WITH_DELIMITED_COLUMN"
ID SERIAL PRIMARY KEY,
"ORG.XTUNIT.IDENTIFIER" VARCHAR(100),
"STYPE" VARCHAR(100)
);
);
CREATE TABLE ENTITY_WITH_SEQUENCE
(
ID BIGINT,
NAME VARCHAR(100)
);
CREATE SEQUENCE ENTITY_SEQUENCE START WITH 1 INCREMENT BY 1 NO MAXVALUE;