Skip to content

Commit 26bbaac

Browse files
committed
HHH-12866 test showing problem is fixed
original author of test was @jedichenbin
1 parent 7632220 commit 26bbaac

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.locking;
6+
7+
import jakarta.persistence.Column;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.GeneratedValue;
10+
import jakarta.persistence.Id;
11+
import jakarta.persistence.JoinColumn;
12+
import jakarta.persistence.OneToOne;
13+
import jakarta.persistence.Table;
14+
import org.hibernate.annotations.GenericGenerator;
15+
16+
@Entity
17+
@Table(name = "T_LOCK_B")
18+
public class B {
19+
20+
private Long id;
21+
private A a;
22+
private String value;
23+
24+
public B() {
25+
}
26+
27+
public B(String value) {
28+
this.value = value;
29+
}
30+
31+
@Id
32+
@GeneratedValue(generator = "increment")
33+
@GenericGenerator(name = "increment", strategy = "increment")
34+
public Long getId() {
35+
return id;
36+
}
37+
38+
public void setId(Long id) {
39+
this.id = id;
40+
}
41+
42+
@Column(name = "b_value")
43+
public String getValue() {
44+
return value;
45+
}
46+
47+
public void setValue(String value) {
48+
this.value = value;
49+
}
50+
51+
@OneToOne
52+
@JoinColumn(name = "a_id")
53+
public A getA() {
54+
return a;
55+
}
56+
57+
public void setA(A a) {
58+
this.a = a;
59+
}
60+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.locking;
6+
7+
import org.hibernate.LockMode;
8+
import org.hibernate.Session;
9+
import org.hibernate.boot.SessionFactoryBuilder;
10+
import org.hibernate.dialect.OracleDialect;
11+
import org.hibernate.dialect.PostgreSQLDialect;
12+
import org.hibernate.testing.RequiresDialect;
13+
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
14+
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
15+
import org.hibernate.testing.orm.junit.JiraKey;
16+
import org.junit.Before;
17+
import org.junit.Test;
18+
19+
import java.util.regex.Matcher;
20+
import java.util.regex.Pattern;
21+
22+
import static java.util.regex.Pattern.CASE_INSENSITIVE;
23+
import static java.util.regex.Pattern.MULTILINE;
24+
import static org.junit.Assert.assertTrue;
25+
26+
/**
27+
* @author Bin Chen ([email protected])
28+
*/
29+
public class PessimisticWriteLockWithAliasTest
30+
extends BaseNonConfigCoreFunctionalTestCase {
31+
32+
private SQLStatementInterceptor sqlStatementInterceptor;
33+
34+
@Override
35+
protected Class<?>[] getAnnotatedClasses() {
36+
return new Class[]{ A.class, B.class };
37+
}
38+
39+
@Override
40+
protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) {
41+
sqlStatementInterceptor = new SQLStatementInterceptor( sfb );
42+
}
43+
44+
private A entityA;
45+
private B entityB;
46+
47+
@Before
48+
public void createTestData() {
49+
Session session = sessionFactory().openSession();
50+
session.beginTransaction();
51+
try {
52+
entityA = new A();
53+
session.persist( entityA );
54+
entityB = new B( "foo" );
55+
entityB.setA( entityA );
56+
session.persist( entityB );
57+
}
58+
finally {
59+
session.getTransaction().commit();
60+
session.close();
61+
}
62+
}
63+
64+
@Test @JiraKey("HHH-12866")
65+
@RequiresDialect(OracleDialect.class)
66+
@RequiresDialect(PostgreSQLDialect.class)
67+
public void testSetLockModeWithAlias() {
68+
69+
Session session = sessionFactory().openSession();
70+
session.beginTransaction();
71+
try {
72+
session.createQuery(
73+
"select b from B b left join fetch b.a", B.class )
74+
.unwrap( org.hibernate.query.Query.class )
75+
.setLockMode( "b", LockMode.PESSIMISTIC_WRITE )
76+
.list();
77+
78+
/*
79+
* The generated SQL would be like: <pre> select b0_.id as id1_1_0_, a1_.id as id1_0_1_, b0_.a_id as
80+
* a_id3_1_0_, b0_.b_value as b_value2_1_0_, a1_.a_value as a_value2_0_1_ from T_LOCK_B b0_ left outer join
81+
* T_LOCK_A a1_ on b0_.a_id=a1_.id for update of b0_.id </pre>
82+
*/
83+
String lockingQuery = sqlStatementInterceptor.getSqlQueries().getLast().toLowerCase();
84+
85+
// attempt to get the alias that is specified in the from clause
86+
Pattern fromTableAliasPattern = Pattern.compile( "from t_lock_b (\\S+)", CASE_INSENSITIVE | MULTILINE );
87+
Matcher aliasGroup = fromTableAliasPattern.matcher( lockingQuery );
88+
assertTrue( "Fail to locate alias in the from clause: " + lockingQuery, aliasGroup.find() );
89+
assertTrue( "Actual query: " + lockingQuery,
90+
lockingQuery.endsWith( " for update of " + aliasGroup.group( 1 ) + ".id" ) // Oracle
91+
|| lockingQuery.endsWith( " for no key update of " + aliasGroup.group( 1 ) ) ); // PostgreSQL
92+
}
93+
finally {
94+
session.getTransaction().commit();
95+
session.close();
96+
}
97+
}
98+
99+
}

0 commit comments

Comments
 (0)