以下是与此问题相关的一些实验。我使用Hibernate 4.3.6作为JPA提供程序,MySQL 5.6作为数据库。
测试实体有几个 - TestPerson,TestUser,TestOrder。
TestUser通过JOINED继承扩展了TestPerson,并且TestUser具有双向的OneToMany TestOrders列表。
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class TestPerson {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String name;
private String address;
@Entity
public class TestUser extends TestPerson {
@OneToMany(fetch=FetchType.LAZY,mappedBy="user")
private List<TestOrder> orders ;
@Entity
public class TestOrder {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@ManyToOne
@JoinTable(name="test_user_orders")
private TestUser user;
private String orderNumber ;
数据创建代码:
em.getTransaction().begin();
TestUser user = new TestUser();
user.setName("TestUser"+System.currentTimeMillis());
user.setAddress("TestUserAddress1");
em.persist(user);
List<TestOrder> orders = new ArrayList();
for (int i=1;i<6;i++){
TestOrder order = new TestOrder();
order.setOrderNumber("ON"+System.currentTimeMillis());
order.setUser(user);
em.persist(order);
orders.add(order);
}
user.setOrders(orders);
em.getTransaction().commit();
em.close();
mysql> select * from test_person;
+
| id | address | name |
+
| 1 | TestUserAddress1 | TestUser1406031063539 |
+
1 row in set (0.00 sec)
mysql> select * from test_user;
+
| id |
+
| 1 |
+
mysql> select * from test_order;
+
| id | order_number |
+
| 1 | ON1406031063627 |
| 2 | ON1406031063673 |
| 3 | ON1406031063678 |
| 4 | ON1406031063683 |
| 5 | ON1406031063686 |
+
mysql> select * from test_user_orders;
+
| user | id |
+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
+
现在正在查找多对一关系的一侧,即TestOrder
Map<String, Object> map = new HashMap<String, Object>()
map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED)
TestOrder order = em2.find(TestOrder.class, new Long(1), LockModeType.PESSIMISTIC_WRITE, map)
请注意查询中的“for update”,这是悲观锁定。该查询还包括联接表。
select
testorder0_.id as id1_8_0_,
testorder0_.order_number as order_nu2_8_0_,
testorder0_1_.user as user1_11_0_
from
test_order testorder0_
left outer join
test_user_orders testorder0_1_
on testorder0_.id=testorder0_1_.id
where
testorder0_.id=? for update
Hibernate:
select
testuser0_.id as id1_9_0_,
testuser0_1_.address as address2_9_0_,
testuser0_1_.name as name3_9_0_
from
test_user testuser0_
inner join
test_person testuser0_1_
on testuser0_.id=testuser0_1_.id
where
testuser0_.id=?
当我查询用户时,这次只有与用户层次结构相关的表被“for update”锁定。
Map<String, Object> map = new HashMap<String, Object>()
map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED)
TestUser user = em2.find(TestUser.class, new Long(2), LockModeType.PESSIMISTIC_WRITE,map)
user.getOrders().size()
生成的 SQL 是:
select
testuser0_.id as id1_9_0_,
testuser0_1_.address as address2_9_0_,
testuser0_1_.name as name3_9_0_
from
test_user testuser0_
inner join
test_person testuser0_1_
on testuser0_.id=testuser0_1_.id
where
testuser0_.id=? for update
Hibernate:
select
orders0_.user as user1_9_0_,
orders0_.id as id2_11_0_,
testorder1_.id as id1_8_1_,
testorder1_.order_number as order_nu2_8_1_,
testorder1_1_.user as user1_11_1_
from
test_user_orders orders0_
inner join
test_order testorder1_
on orders0_.id=testorder1_.id
left outer join
test_user_orders testorder1_1_
on testorder1_.id=testorder1_1_.id
where
orders0_.user=?
PessimisticLockScope
文档中有您问题的答案。 - Vlad Mihalcea