|
13 | 13 | import java.util.Objects; |
14 | 14 | import java.util.Set; |
15 | 15 |
|
| 16 | +import org.hibernate.StaleStateException; |
16 | 17 | import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; |
17 | 18 | import org.hibernate.engine.jdbc.mutation.ParameterUsage; |
18 | 19 | import org.hibernate.engine.jdbc.mutation.group.PreparedStatementDetails; |
|
25 | 26 | import org.hibernate.engine.jdbc.spi.MutationStatementPreparer; |
26 | 27 | import org.hibernate.engine.spi.SessionFactoryImplementor; |
27 | 28 | import org.hibernate.engine.spi.SharedSessionContractImplementor; |
| 29 | +import org.hibernate.exception.ConstraintViolationException; |
28 | 30 | import org.hibernate.internal.util.collections.CollectionHelper; |
29 | 31 | import org.hibernate.jdbc.Expectation; |
30 | 32 | import org.hibernate.persister.entity.mutation.EntityMutationTarget; |
|
52 | 54 | import org.hibernate.sql.model.internal.TableUpdateCustomSql; |
53 | 55 | import org.hibernate.sql.model.internal.TableUpdateStandard; |
54 | 56 |
|
| 57 | +import static org.hibernate.exception.ConstraintViolationException.ConstraintKind.UNIQUE; |
55 | 58 | import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER; |
56 | 59 |
|
57 | 60 | /** |
@@ -152,20 +155,28 @@ public void performMutation( |
152 | 155 | wasUpdated = false; |
153 | 156 | } |
154 | 157 |
|
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 | + } |
161 | 174 | } |
162 | 175 | } |
| 176 | + finally { |
| 177 | + jdbcValueBindings.afterStatement( tableMapping ); |
| 178 | + } |
163 | 179 | } |
164 | | - finally { |
165 | | - jdbcValueBindings.afterStatement( tableMapping ); |
166 | | - } |
167 | | - |
168 | | - } |
169 | 180 |
|
170 | 181 | private void performDelete(JdbcValueBindings jdbcValueBindings, SharedSessionContractImplementor session) { |
171 | 182 | final JdbcDeleteMutation jdbcDelete = createJdbcDelete( session ); |
|
0 commit comments