Support specification of a schema in Column annotations.
Closes #1099 Original pull request #1108
This commit is contained in:
committed by
Jens Schauder
parent
cdff3850ae
commit
d12146d78c
@@ -17,6 +17,7 @@ package org.springframework.data.relational.core.mapping;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.data.util.Lazy;
|
||||
@@ -29,12 +30,14 @@ import org.springframework.util.StringUtils;
|
||||
* @author Jens Schauder
|
||||
* @author Greg Turnquist
|
||||
* @author Bastian Wilhelm
|
||||
* @author Mikhail Polivakha
|
||||
*/
|
||||
class RelationalPersistentEntityImpl<T> extends BasicPersistentEntity<T, RelationalPersistentProperty>
|
||||
implements RelationalPersistentEntity<T> {
|
||||
|
||||
private final NamingStrategy namingStrategy;
|
||||
private final Lazy<Optional<SqlIdentifier>> tableName;
|
||||
private final Lazy<Optional<SqlIdentifier>> schemaName;
|
||||
private boolean forceQuote = true;
|
||||
|
||||
/**
|
||||
@@ -43,16 +46,20 @@ class RelationalPersistentEntityImpl<T> extends BasicPersistentEntity<T, Relatio
|
||||
* @param information must not be {@literal null}.
|
||||
*/
|
||||
RelationalPersistentEntityImpl(TypeInformation<T> information, NamingStrategy namingStrategy) {
|
||||
|
||||
super(information);
|
||||
final Optional<Table> optionalTableAnnotation = Optional.ofNullable(findAnnotation(Table.class));
|
||||
|
||||
this.namingStrategy = namingStrategy;
|
||||
this.tableName = Lazy.of(() -> Optional.ofNullable( //
|
||||
findAnnotation(Table.class)) //
|
||||
.map(Table::value) //
|
||||
.filter(StringUtils::hasText) //
|
||||
.map(this::createSqlIdentifier) //
|
||||
this.tableName = Lazy.of(() -> optionalTableAnnotation
|
||||
.map(Table::value)
|
||||
.filter(StringUtils::hasText)
|
||||
.map(this::createSqlIdentifier)
|
||||
);
|
||||
|
||||
this.schemaName = Lazy.of(() -> optionalTableAnnotation
|
||||
.map(Table::schema)
|
||||
.filter(StringUtils::hasText)
|
||||
.map(this::createSqlIdentifier));
|
||||
}
|
||||
|
||||
private SqlIdentifier createSqlIdentifier(String name) {
|
||||
@@ -77,14 +84,30 @@ class RelationalPersistentEntityImpl<T> extends BasicPersistentEntity<T, Relatio
|
||||
*/
|
||||
@Override
|
||||
public SqlIdentifier getTableName() {
|
||||
return tableName.get().orElseGet(() -> {
|
||||
final Optional<SqlIdentifier> schema = determineCurrentEntitySchema();
|
||||
final Optional<SqlIdentifier> explicitlySpecifiedTableName = tableName.get();
|
||||
if (schema.isPresent()) {
|
||||
return explicitlySpecifiedTableName
|
||||
.map(sqlIdentifier -> SqlIdentifier.from(schema.get(), sqlIdentifier))
|
||||
.orElse(SqlIdentifier.from(schema.get(), createDerivedSqlIdentifier(namingStrategy.getTableName(getType()))));
|
||||
} else {
|
||||
return explicitlySpecifiedTableName.orElse(createDerivedSqlIdentifier(namingStrategy.getTableName(getType())));
|
||||
}
|
||||
}
|
||||
|
||||
String schema = namingStrategy.getSchema();
|
||||
SqlIdentifier tableName = createDerivedSqlIdentifier(namingStrategy.getTableName(getType()));
|
||||
|
||||
return StringUtils.hasText(schema) ? SqlIdentifier.from(createDerivedSqlIdentifier(schema), tableName)
|
||||
: tableName;
|
||||
});
|
||||
/**
|
||||
* @return Optional of {@link SqlIdentifier} representing the current entity schema. If the schema is not specified neither
|
||||
* explicitly, nor via {@link NamingStrategy}, then return {@link Optional#empty()}
|
||||
*/
|
||||
@NotNull
|
||||
private Optional<SqlIdentifier> determineCurrentEntitySchema() {
|
||||
final Optional<SqlIdentifier> explicitlySpecifiedSchema = schemaName.get();
|
||||
if (explicitlySpecifiedSchema.isPresent()) {
|
||||
return explicitlySpecifiedSchema;
|
||||
}
|
||||
return StringUtils.hasText(namingStrategy.getSchema())
|
||||
? Optional.of(createDerivedSqlIdentifier(namingStrategy.getSchema()))
|
||||
: Optional.empty();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.relational.core.mapping;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
@@ -27,6 +29,7 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* @author Kazuki Shimizu
|
||||
* @author Bastian Wilhelm
|
||||
* @author Mikhail Polivakha
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@@ -37,5 +40,23 @@ public @interface Table {
|
||||
/**
|
||||
* The mapping table name.
|
||||
*/
|
||||
@AliasFor("name")
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
/**
|
||||
* The mapping table name.
|
||||
*/
|
||||
@AliasFor("value")
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* Name of the schema (or user, for example in case of oracle), in which this table resides in
|
||||
* The behavior is the following: <br/>
|
||||
* If the {@link Table#schema()} is specified, then it will be
|
||||
* used as a schema of current table, i.e. as a prefix to the name of the table, which can
|
||||
* be specified in {@link Table#value()}. <br/>
|
||||
* If the {@link Table#schema()} is not specified, then spring data will assume the default schema,
|
||||
* The default schema itself can be provided by the means of {@link NamingStrategy#getSchema()}
|
||||
*/
|
||||
String schema() default "";
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
* @author Kazuki Shimizu
|
||||
* @author Bastian Wilhelm
|
||||
* @author Mark Paluch
|
||||
* @author Mikhail Polivakha
|
||||
*/
|
||||
public class RelationalPersistentEntityImplUnitTests {
|
||||
|
||||
@@ -72,6 +73,33 @@ public class RelationalPersistentEntityImplUnitTests {
|
||||
.isEqualTo("\"MY_SCHEMA\".\"DUMMY_ENTITY_WITH_EMPTY_ANNOTATION\"");
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-1099
|
||||
void testRelationalPersistentEntitySchemaNameChoice() {
|
||||
mappingContext = new RelationalMappingContext(NamingStrategyWithSchema.INSTANCE);
|
||||
final RelationalPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(EntityWithExplicitSchema.class);
|
||||
final SqlIdentifier tableName = persistentEntity.getTableName();
|
||||
assertThat(tableName).isEqualTo(SqlIdentifier.from(SqlIdentifier.quoted("DART_VADER"), quoted("I_AM_THE_SENATE")));
|
||||
assertThat(tableName.toString()).isEqualTo("\"DART_VADER\".\"I_AM_THE_SENATE\"");
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-1099
|
||||
void testRelationalPersistentEntityTableOnlySchemaSpecified() {
|
||||
final RelationalPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(EntityWithSchemaFromNamingStrategy.class);
|
||||
final SqlIdentifier tableName = persistentEntity.getTableName();
|
||||
assertThat(tableName).isEqualTo(SqlIdentifier.from(quoted("ANAKYN_SKYWALKER"), quoted("ENTITY_WITH_SCHEMA_FROM_NAMING_STRATEGY")));
|
||||
assertThat(tableName.toString()).isEqualTo("\"ANAKYN_SKYWALKER\".\"ENTITY_WITH_SCHEMA_FROM_NAMING_STRATEGY\"");
|
||||
}
|
||||
|
||||
@Table(schema = "ANAKYN_SKYWALKER")
|
||||
static class EntityWithSchemaFromNamingStrategy {
|
||||
@Id private Long id;
|
||||
}
|
||||
|
||||
@Table(schema = "DART_VADER", name = "I_AM_THE_SENATE")
|
||||
static class EntityWithExplicitSchema {
|
||||
@Id private Long id;
|
||||
}
|
||||
|
||||
@Table("dummy_sub_entity")
|
||||
static class DummySubEntity {
|
||||
@Id @Column("renamedId") Long id;
|
||||
|
||||
Reference in New Issue
Block a user