Skip to content

Commit e225ef2

Browse files
ettavoltbeikov
andauthored
HHH-18621 Restore hibernate.jdbc.batch_versioned_data function.
HHH-18621 Restore hibernate.jdbc.batch_versioned_data function. It, particularly, enables reporting the exact entity that failed optimistic lock. --------- Co-authored-by: Christian Beikov <christian.beikov@gmail.com>
1 parent d4b084a commit e225ef2

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ protected BatchKeyAccess resolveBatchKeyAccess(boolean dynamicUpdate, SharedSess
6868
if ( !dynamicUpdate
6969
&& !entityPersister().optimisticLockStyle().isAllOrDirty()
7070
&& session.getTransactionCoordinator() != null
71-
&& session.getTransactionCoordinator().isTransactionActive() ) {
71+
&& session.getTransactionCoordinator().isTransactionActive()
72+
&& (
73+
session.getSessionFactory().getSessionFactoryOptions().isJdbcBatchVersionedData()
74+
|| !entityPersister().isVersioned() ) ) {
7275
return this::getBatchKey;
7376
}
7477

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.hibernate.orm.test.batch;
2+
3+
import java.io.Serializable;
4+
import java.util.List;
5+
6+
import org.hibernate.cfg.BatchSettings;
7+
8+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
9+
import org.hibernate.testing.orm.junit.JiraKey;
10+
import org.hibernate.testing.orm.junit.Jpa;
11+
import org.hibernate.testing.orm.junit.Setting;
12+
import org.junit.jupiter.api.Assertions;
13+
import org.junit.jupiter.api.Test;
14+
15+
import jakarta.persistence.Entity;
16+
import jakarta.persistence.GeneratedValue;
17+
import jakarta.persistence.GenerationType;
18+
import jakarta.persistence.Id;
19+
import jakarta.persistence.OptimisticLockException;
20+
import jakarta.persistence.RollbackException;
21+
import jakarta.persistence.Version;
22+
23+
@Jpa(
24+
annotatedClasses = BatchOffOnlyForOptimisticallyLocked.Something.class,
25+
properties = {
26+
@Setting(name = BatchSettings.STATEMENT_BATCH_SIZE, value = "10"),
27+
@Setting(name = BatchSettings.BATCH_VERSIONED_DATA, value = "false")
28+
}
29+
)
30+
@JiraKey( "HHH-18621" )
31+
@SkipForDialect(dialectClass = MariaDBDialect.class, majorVersion = 11, minorVersion = 6, microVersion = 2, reason = "MariaDB will throw an error DB_RECORD_CHANGED when acquiring a lock on a record that have changed")
32+
public class BatchOffOnlyForOptimisticallyLocked {
33+
@Test
34+
public void testMultiUpdateOfConcurrentlyModified(EntityManagerFactoryScope scope) {
35+
scope.inTransaction( em -> {
36+
em.persist( new Something( "First" ) );
37+
em.persist( new Something( "Second" ) );
38+
} );
39+
40+
final RollbackException ex = Assertions.assertThrows( RollbackException.class, () -> {
41+
scope.inTransaction( em -> {
42+
final List<Something> subjects = em.createQuery( "select s from Something s", Something.class )
43+
.getResultList();
44+
scope.inTransaction(
45+
competitorEm -> competitorEm.find( Something.class, subjects.get( 0 ).id ).name = "Outrun"
46+
);
47+
for ( Something something : subjects ) {
48+
something.name += " modified";
49+
}
50+
} );
51+
} );
52+
Assertions.assertInstanceOf( OptimisticLockException.class, ex.getCause(), "The cause of rollback" );
53+
Assertions.assertNotNull( ( (OptimisticLockException) ex.getCause() ).getEntity(), "OLE references an entity" );
54+
}
55+
56+
//Has to be Serializable, otherwise it is not deemed safe to include in the OLE.
57+
@Entity(name = "Something")
58+
public static class Something implements Serializable {
59+
@Id
60+
@GeneratedValue(strategy = GenerationType.IDENTITY)
61+
public Long id;
62+
public String name;
63+
@Version
64+
public long version;
65+
66+
public Something() {
67+
}
68+
69+
public Something(String name) {
70+
this.name = name;
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)