HHH-17949 Fix upsert handling when optimistic locking is involved
This commit is contained in:
parent
ab3e4e27e0
commit
b51acb752d
|
@ -215,7 +215,7 @@ public class SqlAstTranslatorWithUpsert<T extends JdbcOperation> extends Abstrac
|
|||
appendSql(" and ");
|
||||
}
|
||||
binding.getColumnReference().appendColumnForWrite( this, "t" );
|
||||
appendSql("<=");
|
||||
appendSql("=");
|
||||
binding.getValueExpression().accept( this );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -386,21 +386,24 @@ public class OptionalTableUpdateOperation implements SelfExecutingUpdateOperatio
|
|||
|
||||
final BindingGroup bindingGroup = jdbcValueBindings.getBindingGroup( tableMapping.getTableName() );
|
||||
if ( bindingGroup != null ) {
|
||||
bindingGroup.forEachBinding( (binding) -> {
|
||||
try {
|
||||
binding.getValueBinder().bind(
|
||||
insertStatement,
|
||||
binding.getValue(),
|
||||
binding.getPosition(),
|
||||
session
|
||||
);
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw session.getJdbcServices().getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Unable to bind parameter for upsert insert",
|
||||
jdbcInsert.getSqlString()
|
||||
);
|
||||
bindingGroup.forEachBinding( binding -> {
|
||||
// Skip parameter bindings for e.g. optimistic version check
|
||||
if ( binding.getPosition() <= jdbcInsert.getParameterBinders().size() ) {
|
||||
try {
|
||||
binding.getValueBinder().bind(
|
||||
insertStatement,
|
||||
binding.getValue(),
|
||||
binding.getPosition(),
|
||||
session
|
||||
);
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw session.getJdbcServices().getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Unable to bind parameter for upsert insert",
|
||||
jdbcInsert.getSqlString()
|
||||
);
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
|
|
@ -3,12 +3,7 @@ package org.hibernate.orm.test.stateless;
|
|||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Version;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -18,10 +13,6 @@ import static org.junit.Assert.assertEquals;
|
|||
@SessionFactory
|
||||
@DomainModel(annotatedClasses = UpsertVersionedTest.Record.class)
|
||||
public class UpsertVersionedTest {
|
||||
@RequiresDialect(OracleDialect.class)
|
||||
@RequiresDialect(H2Dialect.class)
|
||||
@RequiresDialect(SQLServerDialect.class)
|
||||
@RequiresDialect(value = PostgreSQLDialect.class, matchSubTypes = false)
|
||||
@Test void test(SessionFactoryScope scope) {
|
||||
scope.inStatelessTransaction(s-> {
|
||||
s.upsert(new Record(123L,null,"hello earth"));
|
||||
|
@ -32,21 +23,21 @@ public class UpsertVersionedTest {
|
|||
assertEquals("hello mars",s.get(Record.class,456L).message);
|
||||
});
|
||||
scope.inStatelessTransaction(s-> {
|
||||
s.upsert(new Record(123L,1L,"goodbye earth"));
|
||||
s.upsert(new Record(123L,0L,"goodbye earth"));
|
||||
});
|
||||
scope.inStatelessTransaction(s-> {
|
||||
assertEquals("goodbye earth",s.get(Record.class,123L).message);
|
||||
assertEquals("hello mars",s.get(Record.class,456L).message);
|
||||
});
|
||||
scope.inStatelessTransaction(s-> {
|
||||
s.upsert(new Record(456L,4L,"goodbye mars"));
|
||||
s.upsert(new Record(456L,3L,"goodbye mars"));
|
||||
});
|
||||
scope.inStatelessTransaction(s-> {
|
||||
assertEquals("goodbye earth",s.get(Record.class,123L).message);
|
||||
assertEquals("goodbye mars",s.get(Record.class,456L).message);
|
||||
});
|
||||
}
|
||||
@Entity
|
||||
@Entity(name = "Record")
|
||||
static class Record {
|
||||
@Id Long id;
|
||||
@Version Long version;
|
||||
|
|
Loading…
Reference in New Issue