Spanner schema admin functions for parent-child relationships #910
Conversation
# Conflicts: # spring-cloud-gcp-data-spanner/src/main/java/org/springframework/cloud/gcp/data/spanner/core/admin/SpannerSchemaUtils.java
if (ConversionUtils.isIterableNonByteArrayType( | ||
spannerPersistentProperty.getType())) { | ||
throw new SpannerDataException( | ||
"Embedded properties cannot be collections: " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a limitation of Spanner, or is it just to disambiguate with one-to-many relationship?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EDIT, was answering a question about something else !
So no, this is a check to make sure people don't put a List<EmbeddedObject>
with the annotation @Embedded
because embedded objects are meant to be "flattened" into the containing class (columns merged with those of parents). It wouldn't make sense to flatten a list of that embedded object.
"Could not find suitable Cloud Spanner column inner type for " | ||
+ "property type: " + innerType); | ||
} | ||
ddlString = getTypeDdlString(spannerSupportedInnerType, true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just return the result here? if you do that, the further code can be refactored to avoid using else
spannerPersistentProperty.getMaxColumnLength()); | ||
} | ||
|
||
private void getCreateTableDdlStringsForHierarchy(String parentTable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More explicitly name to say "interleaved"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In-person review notes/changes
spannerPersistentEntity.tableName(), | ||
spannerPersistentProperty.getColumnInnerType(), ddlStrings, | ||
seenClasses)); | ||
seenClasses.add(entityClass); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to add this to seen before recursion call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add test case where two properties have the same inner type to catch this
public String getDropTableDdlString(Class entityClass) { | ||
return "DROP TABLE " | ||
+ this.mappingContext.getPersistentEntity(entityClass).tableName(); | ||
private void getDropTableDdlStringsForHierarchy(Class entityClass, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop DDL and create DDL is very similar, should refactor
@Column(name = "") | ||
String other; | ||
|
||
@OneToMany |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps @Interleaved
public void getCreateDdlHierarchyTest() { | ||
List<String> createStrings = this.spannerSchemaUtils | ||
.getCreateTableDdlStringsForHierarchy(ParentEntity.class); | ||
assertEquals(3, createStrings.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert equals on array of all 3 strings?
return; | ||
} | ||
ddlStrings.add(getCreateTableDdlString(entityClass) + (parentTable == null ? "" | ||
: ", INTERLEAVE IN PARENT " + parentTable + " ON DELETE CASCADE")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should ON DELETE CASCADE
an option through a property?
@meltsufin @dmitry-s changes made from in-person discussion, PTAL |
@@ -86,6 +86,8 @@ | |||
|
|||
private final int keepAliveIntervalMinutes; | |||
|
|||
private final boolean createTableDdlCascadeOnDelete; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This applies only to interleaved tables, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's right
@@ -105,6 +107,8 @@ | |||
this.writeSessionsFraction = gcpSpannerProperties.getWriteSessionsFraction(); | |||
this.keepAliveIntervalMinutes = gcpSpannerProperties | |||
.getKeepAliveIntervalMinutes(); | |||
this.createTableDdlCascadeOnDelete = gcpSpannerProperties | |||
.isCreateTableStatementsCascadeOnDelete(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inconsistency in naming createTableDdlCascadeOnDelete
vs createTableStatementsCascadeOnDelete
.
@@ -40,6 +40,10 @@ | |||
|
|||
private String database; | |||
|
|||
// if True then create-table statements generated will cascade on delete. no-action on delete |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please start sentences with an upper-case letter. Also, use {@code true}
, and {@code false}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
technically (grammatically) these aren't sentences , but will change.
* for generating DDL statements. | ||
* @param spannerEntityProcessor an entity processor that is queried for types that it | ||
* can convert for determining compatible column types when generating DDL statements. | ||
*/ | ||
public SpannerSchemaUtils(SpannerMappingContext mappingContext, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a need for this constructor anymore. You always use the one below, except for one instance in test code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed. Made requested changes.
@@ -47,76 +52,47 @@ | |||
|
|||
private final SpannerTypeMapper spannerTypeMapper; | |||
|
|||
private final boolean createTableDdlDeleteOnCascade; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still different from createTableStatementsCascadeOnDelete
. Also, I think a better name would actually indicate that this is for interleaved tables. Maybe createInterleavedTableCascadeOnDelete
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I can change to that new name everywhere. (originally I felt it was OK to have "Ddl" in this class because so many things in this class have those letters in the name, and it would have more meaning given the context of this class and all the "Ddl" related functions.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createTableStatementsCascadeOnDelete
to use DDL
in the name.
Actually, I'm leaning towards this name now:
createInterleavedTableDdlOnDeleteCascade
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed in all 3 places to createInterleavedTableDdlOnDeleteCascade
and merged in other PRs and resolved conflicts.
I'll update the ref doc PR for this new name, too.
# Conflicts: # spring-cloud-gcp-data-spanner/src/main/java/org/springframework/cloud/gcp/data/spanner/core/mapping/SpannerPersistentEntity.java # spring-cloud-gcp-data-spanner/src/main/java/org/springframework/cloud/gcp/data/spanner/core/mapping/SpannerPersistentEntityImpl.java # spring-cloud-gcp-data-spanner/src/test/java/org/springframework/cloud/gcp/data/spanner/core/mapping/SpannerPersistentEntityImplTests.java
@ChengyuanZhao I think you need to resolve conflicts before merging. |
related #853