gpt4 book ai didi

java - 防止 hibernate 实体更改被持久化

转载 作者:行者123 更新时间:2023-12-01 22:56:00 25 4
gpt4 key购买 nike

我正在将我的应用程序从 Spring Boot 1.4.5/Hibernate 4.3.5 更新到 Spring Boot 2.0.9/Hibernate 5.2.18,并且用于在以前的配置中工作的代码不再工作。

场景如下:

  1. 通过输入带有@Transactional注释的方法来启动事务
  2. 使实体水合
  3. 更改实体
  4. 再次查询
  5. 检测到问题。由于此问题,请确定更改不应持续存在。
  6. 驱逐实体
  7. 退出方法/事务

在 Hibernate 4.3.5 中,调用entityManager.detach() 会阻止更改被持久化。然而,在 Hibernate 5.2.18 中,我发现即使进行此调用,更改仍然存在。我还尝试从 session 中驱逐(),并尝试从 session 中清除()所有实体(只是为了看看会发生什么)。

所以我问 - 是否可以像我在 Hibernate 4.3.5 中那样放弃 Hibernate 5.2.18 中的实体更改?

相关代码如下...

@Entity
public class Agreement {

private Long agreementId;
private Integer agreementStateId;

@Id
@Column(name = "agreement_id")
public Long getAgreementId() {
return agreementId;
}

public void setAgreementId(Long agreementId) {
this.agreementId = agreementId;
}

@Basic
@Column(name = "agreement_state_id", nullable = false)
public Integer getAgreementStateId() {
return agreementStateId;
}

public void setAgreementStateId(Integer agreementStateId) {
this.agreementStateId = agreementStateId;
}
}


@Component
public class Repo1 {

@PersistenceContext(unitName = "rights")
private EntityManager entityManager;

public void evict(Object entity) {
entityManager.detach(entity);
}

public Agreement getAgreement(Long agreementId) {
// Code to get entity is here.
// Agreement with an agreementStateId of 5 is returned.
}

public void anotherQuery() {
// Code to make another query is here.
}
}


@Component
public class Service1 {

@Autowired
Repo1 repo;

@Transactional
public void doSomething() {
Agreement agreement = repo.getAgreement(1L);

// Change agreementStateId. Very simple for purposes of example.
agreement.setAgreementStateId(100);

// Make another query
repo.anotherQuery();

// Detect a problem here. Simplified for purposes of example.
if (agreement.getAgreementStateId() == 100) {
repo.evict(agreement);
}
}
}

最佳答案

我已经发现这个问题了,和evict()无关。事实证明,额外的查询导致 session 在 evict() 调用之前刷新。

一般来说,应用程序使用QueryDSL来进行查询。以这种方式进行的查询不会导致在进行查询之前刷新 session 。但在本例中,查询是通过 Session.createSQLQuery() 创建的。这使用已分配给 session 的 FlushMode,即 FlushMode.AUTO。

在进行查询之前,我可以通过在查询上调用 setHibernateFlushMode(FlushMode.COMMIT) 来防止刷新。这会导致 session FlushMode 暂时更改,直到运行查询之后。之后,evict() 调用按预期工作。

关于java - 防止 hibernate 实体更改被持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58440115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com