1717import org .hibernate .boot .model .relational .SqlStringGenerationContext ;
1818import org .hibernate .engine .spi .SharedSessionContractImplementor ;
1919import org .hibernate .id .factory .spi .StandardGenerator ;
20+ import org .hibernate .property .access .spi .Setter ;
21+ import org .hibernate .type .CompositeType ;
2022
2123/**
2224 * For composite identifiers, defines a number of "nested" generations that
@@ -87,16 +89,35 @@ public interface GenerationPlan extends ExportableProducer {
8789 *
8890 * @param session The current session
8991 * @param incomingObject The entity for which we are generating id
90- * @param injectionContext The context into which the generated value can be injected
9192 */
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 ();
93110 }
94111
95112 private final GenerationContextLocator generationContextLocator ;
113+ private final CompositeType compositeType ;
96114 private final List <GenerationPlan > generationPlans = new ArrayList <>();
97115
98- public CompositeNestedGeneratedValueGenerator (GenerationContextLocator generationContextLocator ) {
116+ public CompositeNestedGeneratedValueGenerator (
117+ GenerationContextLocator generationContextLocator ,
118+ CompositeType compositeType ) {
99119 this .generationContextLocator = generationContextLocator ;
120+ this .compositeType = compositeType ;
100121 }
101122
102123 public void addGeneratedValuePlan (GenerationPlan plan ) {
@@ -107,11 +128,29 @@ public void addGeneratedValuePlan(GenerationPlan plan) {
107128 public Object generate (SharedSessionContractImplementor session , Object object ) throws HibernateException {
108129 final Object context = generationContextLocator .locateGenerationContext ( session , object );
109130
131+ final List <Object > generatedValues = compositeType .isMutable () ?
132+ null :
133+ new ArrayList <>( generationPlans .size () );
110134 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+ }
112142 }
113143
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+ }
115154 }
116155
117156 @ Override
0 commit comments