77
88import org .hibernate .HibernateException ;
99import org .hibernate .Internal ;
10+ import org .hibernate .dialect .CockroachDialect ;
1011import org .hibernate .dialect .Dialect ;
12+ import org .hibernate .dialect .MariaDBDialect ;
13+ import org .hibernate .dialect .MySQLDialect ;
14+ import org .hibernate .dialect .OracleDialect ;
1115import org .hibernate .engine .spi .SharedSessionContractImplementor ;
1216import org .hibernate .generator .EventType ;
1317import org .hibernate .generator .values .GeneratedValueBasicResultBuilder ;
1721import org .hibernate .generator .values .internal .GeneratedValuesImpl ;
1822import org .hibernate .generator .values .internal .GeneratedValuesMappingProducer ;
1923import org .hibernate .id .IdentifierGeneratorHelper ;
20- import org .hibernate .id .insert .GetGeneratedKeysDelegate ;
21- import org .hibernate .id .insert .UniqueKeySelectingDelegate ;
2224import org .hibernate .internal .CoreLogging ;
2325import org .hibernate .internal .CoreMessageLogger ;
2426import org .hibernate .metamodel .mapping .ModelPart ;
27+ import org .hibernate .metamodel .mapping .SelectableMapping ;
2528import org .hibernate .persister .entity .EntityPersister ;
2629import org .hibernate .pretty .MessageHelper ;
2730import org .hibernate .query .spi .QueryOptions ;
31+ import org .hibernate .reactive .id .insert .ReactiveGetGeneratedKeysDelegate ;
2832import org .hibernate .reactive .id .insert .ReactiveInsertReturningDelegate ;
33+ import org .hibernate .reactive .id .insert .ReactiveUniqueKeySelectingDelegate ;
2934import org .hibernate .reactive .sql .exec .spi .ReactiveRowProcessingState ;
3035import org .hibernate .reactive .sql .exec .spi .ReactiveValuesResultSet ;
3136import org .hibernate .reactive .sql .results .internal .ReactiveDirectResultSetAccess ;
3843import org .hibernate .sql .results .internal .RowTransformerArrayImpl ;
3944import org .hibernate .sql .results .jdbc .internal .JdbcValuesSourceProcessingStateStandardImpl ;
4045import org .hibernate .sql .results .jdbc .spi .JdbcValuesMappingProducer ;
41- import org .hibernate .sql .results .jdbc .spi .JdbcValuesSourceProcessingOptions ;
4246import org .hibernate .type .descriptor .WrapperOptions ;
4347
4448import java .sql .PreparedStatement ;
5155import static org .hibernate .generator .values .internal .GeneratedValuesHelper .noCustomSql ;
5256import static org .hibernate .internal .NaturalIdHelper .getNaturalIdPropertyNames ;
5357import static org .hibernate .reactive .sql .results .spi .ReactiveListResultsConsumer .UniqueSemantic .NONE ;
58+ import static org .hibernate .sql .results .jdbc .spi .JdbcValuesSourceProcessingOptions .NO_OPTIONS ;
5459
5560/**
5661 * @see org.hibernate.generator.values.internal.GeneratedValuesHelper
@@ -64,13 +69,20 @@ public class ReactiveGeneratedValuesHelper {
6469 * @see GeneratedValuesHelper#getGeneratedValuesDelegate(EntityPersister, EventType)
6570 */
6671 public static GeneratedValuesMutationDelegate getGeneratedValuesDelegate (EntityPersister persister , EventType timing ) {
67- final boolean hasGeneratedProperties = !persister .getGeneratedProperties ( timing ).isEmpty ();
72+ final List <? extends ModelPart > generatedProperties = persister .getGeneratedProperties ( timing );
73+ final boolean hasGeneratedProperties = !generatedProperties .isEmpty ();
6874 final boolean hasRowId = timing == EventType .INSERT && persister .getRowIdMapping () != null ;
6975 final Dialect dialect = persister .getFactory ().getJdbcServices ().getDialect ();
7076
77+ final boolean hasFormula =
78+ generatedProperties .stream ()
79+ .anyMatch ( part -> part instanceof SelectableMapping selectable
80+ && selectable .isFormula () );
81+
82+ boolean supportsInsertReturningRowId = dialect .supportsInsertReturningRowId () || dialect instanceof CockroachDialect ;
7183 if ( hasRowId
72- && dialect . supportsInsertReturning ()
73- && dialect . supportsInsertReturningRowId ()
84+ && supportsInsertReturning ( dialect )
85+ && supportsInsertReturningRowId
7486 && noCustomSql ( persister , timing ) ) {
7587 // Special case for RowId on INSERT, since GetGeneratedKeysDelegate doesn't support it
7688 // make InsertReturningDelegate the preferred method if the dialect supports it
@@ -81,26 +93,32 @@ && noCustomSql( persister, timing ) ) {
8193 return null ;
8294 }
8395
84- if ( dialect .supportsInsertReturningGeneratedKeys ()
85- && persister .getFactory ().getSessionFactoryOptions ().isGetGeneratedKeysEnabled () ) {
86- return new GetGeneratedKeysDelegate ( persister , false , timing );
87- }
88- else if ( supportsReturning ( dialect , timing ) && noCustomSql ( persister , timing ) ) {
96+ if ( supportsReturning ( dialect , timing ) && noCustomSql ( persister , timing ) ) {
8997 return new ReactiveInsertReturningDelegate ( persister , timing );
9098 }
91- else if ( timing == EventType .INSERT && persister .getNaturalIdentifierProperties () != null
92- && !persister .getEntityMetamodel ().isNaturalIdentifierInsertGenerated () ) {
93- return new UniqueKeySelectingDelegate (
94- persister ,
95- getNaturalIdPropertyNames ( persister ),
96- timing
97- );
99+ else if ( !hasFormula && dialect .supportsInsertReturningGeneratedKeys () ) {
100+ return new ReactiveGetGeneratedKeysDelegate ( persister , false , timing );
101+ }
102+ else if ( timing == EventType .INSERT && persister .getNaturalIdentifierProperties () != null && !persister .getEntityMetamodel ()
103+ .isNaturalIdentifierInsertGenerated () ) {
104+ return new ReactiveUniqueKeySelectingDelegate ( persister , getNaturalIdPropertyNames ( persister ), timing );
98105 }
99106 return null ;
100107 }
101108
102- private static boolean supportsReturning (Dialect dialect , EventType timing ) {
103- return timing == EventType .INSERT ? dialect .supportsInsertReturning () : dialect .supportsUpdateReturning ();
109+ public static boolean supportReactiveGetGeneratedKey (Dialect dialect , List <? extends ModelPart > generatedProperties ) {
110+ return dialect instanceof OracleDialect
111+ || (dialect instanceof MySQLDialect && generatedProperties .size () == 1 && !(dialect instanceof MariaDBDialect ));
112+ }
113+
114+ public static boolean supportsReturning (Dialect dialect , EventType timing ) {
115+ return timing == EventType .INSERT
116+ ? supportsInsertReturning (dialect )
117+ : dialect .supportsUpdateReturning () || dialect instanceof CockroachDialect ;
118+ }
119+
120+ public static boolean supportsInsertReturning (Dialect dialect ) {
121+ return dialect .supportsInsertReturning () || dialect instanceof CockroachDialect ;
104122 }
105123
106124 /**
@@ -181,31 +199,9 @@ private static CompletionStage<Object[]> readGeneratedValues(
181199 executionContext
182200 );
183201
184- final JdbcValuesSourceProcessingOptions processingOptions = new JdbcValuesSourceProcessingOptions () {
185- @ Override
186- public Object getEffectiveOptionalObject () {
187- return null ;
188- }
189-
190- @ Override
191- public String getEffectiveOptionalEntityName () {
192- return null ;
193- }
194-
195- @ Override
196- public Object getEffectiveOptionalId () {
197- return null ;
198- }
199-
200- @ Override
201- public boolean shouldReturnProxies () {
202- return true ;
203- }
204- };
205-
206202 final JdbcValuesSourceProcessingStateStandardImpl valuesProcessingState = new JdbcValuesSourceProcessingStateStandardImpl (
207203 executionContext ,
208- processingOptions
204+ NO_OPTIONS
209205 );
210206
211207 final ReactiveRowReader <Object []> rowReader = ReactiveResultsHelper .createRowReader (
@@ -217,7 +213,7 @@ public boolean shouldReturnProxies() {
217213
218214 final ReactiveRowProcessingState rowProcessingState = new ReactiveRowProcessingState ( valuesProcessingState , executionContext , rowReader , jdbcValues );
219215 return ReactiveListResultsConsumer .<Object []>instance ( NONE )
220- .consume ( jdbcValues , session , processingOptions , valuesProcessingState , rowProcessingState , rowReader )
216+ .consume ( jdbcValues , session , NO_OPTIONS , valuesProcessingState , rowProcessingState , rowReader )
221217 .thenApply ( results -> {
222218 if ( results .isEmpty () ) {
223219 throw new HibernateException ( "The database returned no natively generated values : " + persister .getNavigableRole ().getFullPath () );
0 commit comments