17
17
import org .hibernate .boot .model .relational .SqlStringGenerationContext ;
18
18
import org .hibernate .engine .spi .SharedSessionContractImplementor ;
19
19
import org .hibernate .id .factory .spi .StandardGenerator ;
20
+ import org .hibernate .property .access .spi .Setter ;
21
+ import org .hibernate .type .CompositeType ;
20
22
21
23
/**
22
24
* For composite identifiers, defines a number of "nested" generations that
@@ -87,16 +89,35 @@ public interface GenerationPlan extends ExportableProducer {
87
89
*
88
90
* @param session The current session
89
91
* @param incomingObject The entity for which we are generating id
90
- * @param injectionContext The context into which the generated value can be injected
91
92
*/
92
- void execute (SharedSessionContractImplementor session , Object incomingObject , Object injectionContext );
93
+ Object execute (SharedSessionContractImplementor session , Object incomingObject );
94
+
95
+ /**
96
+ * Returns the {@link Setter injector} for the generated property.
97
+ * Used when the {@link CompositeType} is {@linkplain CompositeType#isMutable() mutable}.
98
+ *
99
+ * @see #getPropertyIndex()
100
+ */
101
+ Setter getInjector ();
102
+
103
+ /**
104
+ * Returns the index of the generated property.
105
+ * Used when the {@link CompositeType} is not {@linkplain CompositeType#isMutable() mutable}.
106
+ *
107
+ * @see #getInjector()
108
+ */
109
+ int getPropertyIndex ();
93
110
}
94
111
95
112
private final GenerationContextLocator generationContextLocator ;
113
+ private final CompositeType compositeType ;
96
114
private final List <GenerationPlan > generationPlans = new ArrayList <>();
97
115
98
- public CompositeNestedGeneratedValueGenerator (GenerationContextLocator generationContextLocator ) {
116
+ public CompositeNestedGeneratedValueGenerator (
117
+ GenerationContextLocator generationContextLocator ,
118
+ CompositeType compositeType ) {
99
119
this .generationContextLocator = generationContextLocator ;
120
+ this .compositeType = compositeType ;
100
121
}
101
122
102
123
public void addGeneratedValuePlan (GenerationPlan plan ) {
@@ -107,11 +128,29 @@ public void addGeneratedValuePlan(GenerationPlan plan) {
107
128
public Object generate (SharedSessionContractImplementor session , Object object ) throws HibernateException {
108
129
final Object context = generationContextLocator .locateGenerationContext ( session , object );
109
130
131
+ final List <Object > generatedValues = compositeType .isMutable () ?
132
+ null :
133
+ new ArrayList <>( generationPlans .size () );
110
134
for ( GenerationPlan generationPlan : generationPlans ) {
111
- generationPlan .execute ( session , object , context );
135
+ final Object generated = generationPlan .execute ( session , object );
136
+ if ( generatedValues != null ) {
137
+ generatedValues .add ( generated );
138
+ }
139
+ else {
140
+ generationPlan .getInjector ().set ( context , generated );
141
+ }
112
142
}
113
143
114
- return context ;
144
+ if ( generatedValues != null ) {
145
+ final Object [] values = compositeType .getPropertyValues ( context );
146
+ for ( int i = 0 ; i < generatedValues .size (); i ++ ) {
147
+ values [generationPlans .get ( i ).getPropertyIndex ()] = generatedValues .get ( i );
148
+ }
149
+ return compositeType .replacePropertyValues ( context , values , session );
150
+ }
151
+ else {
152
+ return context ;
153
+ }
115
154
}
116
155
117
156
@ Override
0 commit comments