Jer*_*ker 6 mysql hibernate sharding spring-data spring-data-jpa
我正在使用休眠/JPA。
当我执行entity.save()or 时session.update(entity),hibernate 会生成这样的查询:-
update TABLE1 set COL_1=? , COL_2=? , COL_3=? where COL_PK=?
Run Code Online (Sandbox Code Playgroud)
我可以通过实体中的任何注释在 WHERE 子句中包含一个附加列,因此它可以导致如下查询:-
update TABLE1 set COL_1=? , COL_2=? , COL_3=? where COL_PK=? **AND COL_3=?**
Run Code Online (Sandbox Code Playgroud)
这是因为我们的数据库是基于分片的COL_3,这需要出现在 where 子句中
我希望能够仅使用session.update(entity)or来实现这一点entity.save()。
如果我理解正确的话,本质上你所描述的是你希望 hibernate 表现得像你有一个复合主键,即使你的数据库有一个单列主键(其中你还有一个 @Version 列来执行乐观锁定) 。
严格来说,您的休眠模型不需要与您的数据库架构完全匹配。您可以将实体定义为具有复合主键,确保所有更新都基于两个值的组合进行。这里的缺点是您的加载操作稍微复杂一些。
考虑以下实体:
@Entity
@Table(name="test_entity", uniqueConstraints = { @UniqueConstraint(columnNames = {"id"}) })
public class TestEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false, unique = true)
private Long id;
@Id
@Column(name = "col_3", nullable = false)
private String col_3;
@Column(name = "value", nullable = true)
private String value;
@Version
@Column(nullable = false)
private Integer version;
... getters & setters
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用以下方法(在我的例子中,我创建了一个简单的 JUnit 测试)
@Test
public void test() {
TestEntity test = new TestEntity();
test.setCol_3("col_3_value");
test.setValue("first-value");
session.persist(test);
long id = test.getId();
session.flush();
session.clear();
TestEntity loadedTest = (TestEntity) session
.createCriteria(TestEntity.class)
.add(Restrictions.eq("id", id))
.uniqueResult();
loadedTest.setValue("new-value");
session.saveOrUpdate(loadedTest);
session.flush();
}
Run Code Online (Sandbox Code Playgroud)
这会生成以下 SQL 语句(启用 Hibernate 日志记录)
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
test_entity
(value, version, id, col_3)
values
(?, ?, ?, ?)
Hibernate:
select
this_.id as id1_402_0_,
this_.col_3 as col_2_402_0_,
this_.value as value3_402_0_,
this_.version as version4_402_0_
from
test_entity this_
where
this_.id=?
Hibernate:
update
test_entity
set
value=?,
version=?
where
id=?
and col_3=?
and version=?
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这使得加载稍微复杂一些 - 我在这里使用了一个条件,但它满足您的条件,即您的更新语句始终在“where”子句中包含列 col_3。