Skip to content

Commit a51a3be

Browse files
committed
HHH-18953 correctly implement @save with generated id for reactive repos
and use xxxMultiple() for regular repos
1 parent cd9e30d commit a51a3be

File tree

2 files changed

+113
-57
lines changed

2 files changed

+113
-57
lines changed

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,7 +1384,7 @@ else if ( returnArgument
13841384
sessionType,
13851385
operation,
13861386
context.addNonnullAnnotation(),
1387-
isIterableLifecycleParameter(parameterType),
1387+
lifecycleParameterKind(parameterType),
13881388
returnArgument,
13891389
hasGeneratedId(declaredType)
13901390
)
@@ -1405,16 +1405,18 @@ && hasAnnotation(member, ID) ) {
14051405
return false;
14061406
}
14071407

1408-
private static boolean isIterableLifecycleParameter(TypeMirror parameterType) {
1408+
private static LifecycleMethod.ParameterKind lifecycleParameterKind(TypeMirror parameterType) {
14091409
switch (parameterType.getKind()) {
14101410
case ARRAY:
1411-
return true;
1411+
return LifecycleMethod.ParameterKind.ARRAY;
14121412
case DECLARED:
14131413
final DeclaredType declaredType = (DeclaredType) parameterType;
14141414
final TypeElement typeElement = (TypeElement) declaredType.asElement();
1415-
return typeElement.getQualifiedName().contentEquals(LIST);
1415+
return typeElement.getQualifiedName().contentEquals(LIST)
1416+
? LifecycleMethod.ParameterKind.LIST
1417+
: LifecycleMethod.ParameterKind.NORMAL;
14161418
default:
1417-
return false;
1419+
return LifecycleMethod.ParameterKind.NORMAL;
14181420
}
14191421
}
14201422

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/LifecycleMethod.java

Lines changed: 106 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
*/
55
package org.hibernate.processor.annotation;
66

7+
78
import javax.lang.model.element.ExecutableElement;
89

10+
import static org.hibernate.processor.util.Constants.LIST;
911
import static org.hibernate.processor.util.Constants.UNI;
1012

1113
public class LifecycleMethod extends AbstractAnnotatedMethod {
@@ -14,10 +16,16 @@ public class LifecycleMethod extends AbstractAnnotatedMethod {
1416
private final String parameterName;
1517
private final String operationName;
1618
private final boolean addNonnullAnnotation;
17-
private final boolean iterateParameter;
19+
private final ParameterKind parameterKind;
1820
private final boolean returnArgument;
1921
private final boolean hasGeneratedId;
2022

23+
public enum ParameterKind {
24+
NORMAL,
25+
ARRAY,
26+
LIST
27+
}
28+
2129
public LifecycleMethod(
2230
AnnotationMetaEntity annotationMetaEntity,
2331
ExecutableElement method,
@@ -28,7 +36,7 @@ public LifecycleMethod(
2836
String sessionType,
2937
String operationName,
3038
boolean addNonnullAnnotation,
31-
boolean iterateParameter,
39+
ParameterKind parameterKind,
3240
boolean returnArgument,
3341
boolean hasGeneratedId) {
3442
super(annotationMetaEntity, method, sessionName, sessionType);
@@ -37,7 +45,7 @@ public LifecycleMethod(
3745
this.parameterName = parameterName;
3846
this.operationName = operationName;
3947
this.addNonnullAnnotation = addNonnullAnnotation;
40-
this.iterateParameter = iterateParameter;
48+
this.parameterKind = parameterKind;
4149
this.returnArgument = returnArgument;
4250
this.hasGeneratedId = hasGeneratedId;
4351
}
@@ -98,9 +106,10 @@ private void returnArgument(StringBuilder declaration) {
98106
if ( returnArgument ) {
99107
if ( isReactive() ) {
100108
declaration
101-
.append(".replaceWith(")
102-
.append(parameterName)
103-
.append(")");
109+
.append( "\n\t\t\t" )
110+
.append(".replaceWith(")
111+
.append(parameterName)
112+
.append(")");
104113
}
105114
else {
106115
declaration
@@ -112,65 +121,110 @@ private void returnArgument(StringBuilder declaration) {
112121

113122
private void delegateCall(StringBuilder declaration) {
114123
if ( isReactive() ) {
124+
// TODO: handle the case of an iterable parameter
125+
delegateReactively( declaration );
126+
}
127+
else {
128+
delegateBlockingly( declaration );
129+
}
130+
}
131+
132+
private void delegateBlockingly(StringBuilder declaration) {
133+
if ( isGeneratedIdUpsert() ) {
115134
declaration
116-
.append("\treturn ")
117-
.append(sessionName);
118-
if ( isReactiveSessionAccess() ) {
119-
declaration
120-
.append(".chain(")
121-
.append(localSessionName())
122-
.append(" -> ")
123-
.append(localSessionName());
124-
}
125-
declaration
126-
.append('.')
127-
.append(operationName)
128-
.append('(')
135+
.append("\t\tif (")
136+
.append(sessionName)
137+
.append(".getIdentifier(")
129138
.append(parameterName)
130-
.append(')');
131-
if ( isReactiveSessionAccess() ) {
132-
declaration
133-
.append(')');
134-
}
139+
.append(") == null)\n")
140+
.append("\t\t\t")
141+
.append(sessionName)
142+
.append('.')
143+
.append("insert");
144+
argument( declaration, "Multiple" );
145+
declaration
146+
.append(";\n")
147+
.append("\t\telse\n\t");
135148
}
136-
else {
137-
if ( iterateParameter ) {
149+
declaration
150+
.append("\t\t")
151+
.append(sessionName)
152+
.append('.')
153+
.append(operationName);
154+
argument( declaration, "Multiple" );
155+
declaration
156+
.append(";\n");
157+
}
158+
159+
private void argument(StringBuilder declaration, String suffix) {
160+
switch ( parameterKind ) {
161+
case LIST:
138162
declaration
139-
.append("\t\tfor (var _entity : ")
163+
.append(suffix)
164+
.append("(")
140165
.append(parameterName)
141-
.append(") {\n\t");
142-
}
143-
if ( "upsert".equals(operationName) && hasGeneratedId ) {
166+
.append(")");
167+
break;
168+
case ARRAY:
169+
declaration
170+
.append(suffix)
171+
.append("(")
172+
.append(annotationMetaEntity.importType(LIST))
173+
.append(".of(")
174+
.append(parameterName)
175+
.append("))");
176+
break;
177+
default:
144178
declaration
145-
.append("\t\tif (")
146-
.append(sessionName)
147-
.append(".getIdentifier(")
148-
.append(iterateParameter ? "_entity" : parameterName)
149-
.append(") == null)\n")
150-
.append("\t\t\t")
151-
.append(sessionName)
152-
.append('.')
153-
.append("insert")
154179
.append('(')
155-
.append(iterateParameter ? "_entity" : parameterName)
156-
.append(')')
157-
.append(";\n")
158-
.append("\t\telse\n\t");
159-
}
180+
.append(parameterName)
181+
.append(')');
182+
}
183+
}
184+
185+
private void delegateReactively(StringBuilder declaration) {
186+
declaration
187+
.append("\treturn ");
188+
if ( isReactiveSessionAccess() ) {
160189
declaration
161-
.append("\t\t")
162190
.append(sessionName)
191+
.append(".chain(")
192+
.append(localSessionName())
193+
.append(" -> ");
194+
}
195+
if ( isGeneratedIdUpsert() ) {
196+
declaration
197+
.append("(")
198+
.append(localSessionName())
199+
.append(".getIdentifier(")
200+
.append(parameterName)
201+
.append(") == null ? ")
202+
.append(localSessionName())
163203
.append('.')
164-
.append(operationName)
204+
.append("insert")
165205
.append('(')
166-
.append(iterateParameter ? "_entity" : parameterName)
206+
.append(parameterName)
167207
.append(')')
168-
.append(";\n");
169-
if ( iterateParameter ) {
170-
declaration
171-
.append("\t\t}\n");
172-
}
208+
.append(" : ");
173209
}
210+
declaration
211+
.append(localSessionName())
212+
.append( '.' )
213+
.append( operationName );
214+
// note that there is no upsertAll() method
215+
argument( declaration, "All" );
216+
if ( isGeneratedIdUpsert() ) {
217+
declaration
218+
.append(')');
219+
}
220+
if ( isReactiveSessionAccess() ) {
221+
declaration
222+
.append(')');
223+
}
224+
}
225+
226+
private boolean isGeneratedIdUpsert() {
227+
return "upsert".equals( operationName ) && hasGeneratedId;
174228
}
175229

176230
private void preamble(StringBuilder declaration) {

0 commit comments

Comments
 (0)