Skip to content

Commit 195b79f

Browse files
committed
Introduce methods to explain the magic 2s
1 parent 1761ab2 commit 195b79f

File tree

1 file changed

+42
-4
lines changed
  • spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert

1 file changed

+42
-4
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java

+42-4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ class SqlGenerator {
6666
static final SqlIdentifier IDS_SQL_PARAMETER = SqlIdentifier.unquoted("ids");
6767
static final SqlIdentifier ROOT_ID_PARAMETER = SqlIdentifier.unquoted("rootId");
6868

69+
/**
70+
* Length of an aggregate path that is one longer then the root path.
71+
*/
72+
private static final int FIRST_NON_ROOT_LENTH = 2;
73+
6974
private final RelationalPersistentEntity<?> entity;
7075
private final RelationalMappingContext mappingContext;
7176
private final RenderContext renderContext;
@@ -112,6 +117,40 @@ class SqlGenerator {
112117
this.dialect = dialect;
113118
}
114119

120+
/**
121+
* When deleting entities there is a fundamental difference between deleting
122+
* <ol>
123+
* <li>the aggregate root.</li>
124+
* <li>a first level entity which still references the root id directly</li>
125+
* <li>and all other entities which have to use a subselect to navigate from the id of the aggregate root to something
126+
* referenced by the table in question.</li>
127+
* </ol>
128+
* For paths of the second kind this method returns {@literal true}.
129+
*
130+
* @param path the path to analyze.
131+
* @return If the given path is considered deeply nested.
132+
*/
133+
private static boolean isFirstNonRoot(AggregatePath path) {
134+
return path.getLength() == FIRST_NON_ROOT_LENTH;
135+
}
136+
137+
/**
138+
* When deleting entities there is a fundamental difference between deleting
139+
* <ol>
140+
* <li>the aggregate root.</li>
141+
* <li>a first level entity which still references the root id directly</li>
142+
* <li>and all other entities which have to use a subselect to navigate from the id of the aggregate root to something
143+
* referenced by the table in question.</li>
144+
* </ol>
145+
* For paths of the third kind this method returns {@literal true}.
146+
*
147+
* @param path the path to analyze.
148+
* @return If the given path is considered deeply nested.
149+
*/
150+
private static boolean isDeeplyNested(AggregatePath path) {
151+
return path.getLength() > FIRST_NON_ROOT_LENTH;
152+
}
153+
115154
/**
116155
* Construct an IN-condition based on a {@link Select Sub-Select} which selects the ids (or stand-ins for ids) of the
117156
* given {@literal path} to those that reference the root entities specified by the {@literal rootCondition}.
@@ -126,9 +165,8 @@ private Condition getSubselectCondition(AggregatePath path, Function<Column, Con
126165

127166
AggregatePath parentPath = path.getParentPath();
128167

129-
// TODO: Introduce methods to express what >2 and == 2 means
130168
if (!parentPath.hasIdProperty()) {
131-
if (parentPath.getLength() > 2) {
169+
if (isDeeplyNested(parentPath)) {
132170
return getSubselectCondition(parentPath, rootCondition, filterColumn);
133171
}
134172
return rootCondition.apply(filterColumn);
@@ -140,7 +178,7 @@ private Condition getSubselectCondition(AggregatePath path, Function<Column, Con
140178

141179
Condition innerCondition;
142180

143-
if (parentPath.getLength() == 2) { // if the parent is the root of the path
181+
if (isFirstNonRoot(parentPath)) { // if the parent is the root of the path
144182

145183
// apply the rootCondition
146184
innerCondition = rootCondition.apply(selectFilterColumn);
@@ -719,7 +757,7 @@ private String createDeleteByPathAndCriteria(AggregatePath path, Function<Column
719757

720758
Column filterColumn = table.column(path.getTableInfo().reverseColumnInfo().name());
721759

722-
if (path.getLength() == 2) {
760+
if (isFirstNonRoot(path)) {
723761

724762
delete = builder //
725763
.where(rootCondition.apply(filterColumn)) //

0 commit comments

Comments
 (0)