diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SqlAstTranslatorWithMerge.java b/hibernate-core/src/main/java/org/hibernate/dialect/SqlAstTranslatorWithMerge.java index be143614a526..5d646d225fb1 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SqlAstTranslatorWithMerge.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SqlAstTranslatorWithMerge.java @@ -50,6 +50,11 @@ public MergeOperation createMergeOperation(OptionalTableUpdate optionalTableUpda ); } + @Override + public void visitOptionalTableUpdate(OptionalTableUpdate tableUpdate) { + renderMergeStatement(tableUpdate); + } + /** * Renders the OptionalTableUpdate as a MERGE query. * @@ -207,8 +212,9 @@ protected void renderMergeInsert(OptionalTableUpdate optionalTableUpdate) { protected void renderMergeDelete(OptionalTableUpdate optionalTableUpdate) { final List valueBindings = optionalTableUpdate.getValueBindings(); + final List optimisticLockBindings = optionalTableUpdate.getOptimisticLockBindings(); - appendSql( " when matched " ); + renderWhenMatched( optimisticLockBindings ); for ( int i = 0; i < valueBindings.size(); i++ ) { final ColumnValueBinding binding = valueBindings.get( i ); appendSql( " and " ); @@ -220,8 +226,10 @@ protected void renderMergeDelete(OptionalTableUpdate optionalTableUpdate) { protected void renderMergeUpdate(OptionalTableUpdate optionalTableUpdate) { final List valueBindings = optionalTableUpdate.getValueBindings(); + final List optimisticLockBindings = optionalTableUpdate.getOptimisticLockBindings(); - appendSql( " when matched then update set " ); + renderWhenMatched( optimisticLockBindings ); + appendSql( " then update set " ); for ( int i = 0; i < valueBindings.size(); i++ ) { final ColumnValueBinding binding = valueBindings.get( i ); if ( i > 0 ) { @@ -232,4 +240,15 @@ protected void renderMergeUpdate(OptionalTableUpdate optionalTableUpdate) { binding.getColumnReference().appendColumnForWrite( this, "s" ); } } + + private void renderWhenMatched(List optimisticLockBindings) { + appendSql( " when matched" ); + for (int i = 0; i < optimisticLockBindings.size(); i++) { + final ColumnValueBinding binding = optimisticLockBindings.get( i ); + appendSql(" and "); + binding.getColumnReference().appendColumnForWrite( this, "t" ); + appendSql("<="); + binding.getValueExpression().accept( this ); + } + } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/UpsertVersionedTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/UpsertVersionedTest.java index 1ae36bb72a2c..e6363d4f2baf 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/UpsertVersionedTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/stateless/UpsertVersionedTest.java @@ -15,7 +15,7 @@ public class UpsertVersionedTest { @Test void test(SessionFactoryScope scope) { scope.inStatelessTransaction(s-> { - s.upsert(new Record(123L,1L,"hello earth")); + s.upsert(new Record(123L,0L,"hello earth")); s.upsert(new Record(456L,2L,"hello mars")); }); scope.inStatelessTransaction(s-> {