Skip to content

Commit c145678

Browse files
gavinkingmbellade
authored andcommitted
HHH-19522 report failed optimistic lock checking for upsert()
- also fix the problem for upsert emulation with UPDATE/INSERT
1 parent 58df98e commit c145678

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

hibernate-core/src/main/java/org/hibernate/sql/model/jdbc/OptionalTableUpdateOperation.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.Objects;
1414
import java.util.Set;
1515

16+
import org.hibernate.StaleStateException;
1617
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
1718
import org.hibernate.engine.jdbc.mutation.ParameterUsage;
1819
import org.hibernate.engine.jdbc.mutation.group.PreparedStatementDetails;
@@ -25,6 +26,7 @@
2526
import org.hibernate.engine.jdbc.spi.MutationStatementPreparer;
2627
import org.hibernate.engine.spi.SessionFactoryImplementor;
2728
import org.hibernate.engine.spi.SharedSessionContractImplementor;
29+
import org.hibernate.exception.ConstraintViolationException;
2830
import org.hibernate.internal.util.collections.CollectionHelper;
2931
import org.hibernate.jdbc.Expectation;
3032
import org.hibernate.persister.entity.mutation.EntityMutationTarget;
@@ -52,6 +54,7 @@
5254
import org.hibernate.sql.model.internal.TableUpdateCustomSql;
5355
import org.hibernate.sql.model.internal.TableUpdateStandard;
5456

57+
import static org.hibernate.exception.ConstraintViolationException.ConstraintKind.UNIQUE;
5558
import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER;
5659

5760
/**
@@ -152,20 +155,28 @@ public void performMutation(
152155
wasUpdated = false;
153156
}
154157

155-
if ( !wasUpdated ) {
156-
MODEL_MUTATION_LOGGER.debugf(
157-
"Upsert update altered no rows - inserting : %s",
158-
tableMapping.getTableName()
159-
);
160-
performInsert( jdbcValueBindings, session );
158+
if ( !wasUpdated ) {
159+
MODEL_MUTATION_LOGGER.debugf(
160+
"Upsert update altered no rows - inserting : %s",
161+
tableMapping.getTableName()
162+
);
163+
try {
164+
performInsert( jdbcValueBindings, session );
165+
}
166+
catch (ConstraintViolationException cve) {
167+
throw cve.getKind() == UNIQUE
168+
// assume it was the primary key constraint which was violated,
169+
// due to a new version of the row existing in the database
170+
? new StaleStateException( mutationTarget.getRolePath(), cve )
171+
: cve;
172+
}
173+
}
161174
}
162175
}
176+
finally {
177+
jdbcValueBindings.afterStatement( tableMapping );
178+
}
163179
}
164-
finally {
165-
jdbcValueBindings.afterStatement( tableMapping );
166-
}
167-
168-
}
169180

170181
private void performDelete(JdbcValueBindings jdbcValueBindings, SharedSessionContractImplementor session) {
171182
final JdbcDeleteMutation jdbcDelete = createJdbcDelete( session );

hibernate-core/src/test/java/org/hibernate/orm/test/stateless/UpsertVersionedTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import jakarta.persistence.Entity;
88
import jakarta.persistence.Id;
99
import jakarta.persistence.Version;
10-
import org.hibernate.StaleObjectStateException;
10+
import org.hibernate.StaleStateException;
1111
import org.hibernate.testing.orm.junit.DomainModel;
1212
import org.hibernate.testing.orm.junit.SessionFactory;
1313
import org.hibernate.testing.orm.junit.SessionFactoryScope;
@@ -60,7 +60,7 @@ public class UpsertVersionedTest {
6060
} );
6161
fail();
6262
}
63-
catch (StaleObjectStateException sose) {
63+
catch (StaleStateException sse) {
6464
//expected
6565
}
6666
scope.inStatelessTransaction( s-> {

0 commit comments

Comments
 (0)