【发布时间】:2020-04-16 17:23:03
【问题描述】:
我知道这很常见,并且有很多关于合并不更新数据库中的数据的问题。但这有点不同。
从前端单击保存按钮时,我可以看到 CaseSpecimen 中的数据已针对所有三个属性进行了更新,但是当在此对象上调用合并时,它不会更新数据库。返回响应后,如果我再次单击保存按钮,因为该字段具有我想要的数据,在再次对 CaseSpecimen 对象调用合并后,这一次它将数据保存在数据库中。
这种情况只发生在一种标本类型上。 假设我们有针对案例 c 的 2 个样本类型 A 和 B。 如果我更新类型 A 中的值并单击保存,它将更新数据库中的数据。但是如果我对 Type B 做同样的事情,它不会第一次更新数据,但是如果我第二次点击保存按钮,那么数据库中的值将被更新。
SpecModel.java
@Entity
@Table(name = "CASE_SPECIMEN")
@NamedQuery(name = "CaseSpecimen.findAll", query = "SELECT c FROM CaseSpecimen c")
@XmlAccessorType(XmlAccessType.FIELD)
public class CaseSpecimen extendsBaseEntity implements Serializable,
Comparable<CaseSpecimen> {
private static final long serialVersionUID = 1L;
@Column(name = "SPECIMEN_BODY_SITE")
private String bodySite;
@Column(name = "SPECIMEN_PROCEDURE")
private String procedureName;
@Column(name = "SPECIMEN_SOURCE")
private String specimenSource;
...
getters and setters
}
主要实体
@Entity
@Table(name = "`CASE`")
@XmlAccessorType(XmlAccessType.FIELD)
public class Case extends BaseEntity implements Serializable {
public static final String CASE_CODE_SEPERATOR = "-";
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CASE_ID")
@GsonIgnore
@XmlTransient
private int id;
@OneToMany(mappedBy = "patientCase", cascade = { CascadeType.MERGE, CascadeType.PERSIST })
@NotFound(action = NotFoundAction.IGNORE)
private Set<CaseSpecimen> caseSpecimens;
...
getters and setters
}
案例道:
@Singleton
public class CaseDao extends GenericEntityDAO<PendingList> {
@PersistenceContext(name = "APP_DB")
protected EntityManager entityManager;
public CaseSpecimen updateCaseSpecimen(CaseSpecimen specimen) {
return entityManager.merge(specimen);
}
}
即使我在合并后调用了刷新方法,但数据库中仍然没有更新
public CaseSpecimen updateCaseSpecimen(CaseSpecimen specimen) {
CaseSpecimen spec = entityManager.merge(specimen);
entityMannger.flush();
return spec;
}
控制器:
for (CaseSpecimen specimen : case.getCaseSpecimens()) {
... if the updated object from front end the below line will execute
caseSpecimensUpdatedList.add(caseService.updateCaseSpecimen(specimen));
}
CaseService:目前它是一个额外的层。这只是调用道方法。
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="APP_DB" >
<jta-data-source>java:jboss/datasources/AppDataSource</jta-data-source>
<properties>
<property name="jboss.entity.manager.jndi.name" value="java:/AppEntityManager"/>
<property name="wildfly.jpa.default-unit" value="true"/>
<property name="hibernate.default_batch_fetch_size" value="100"/>
<property name="hibernate.event.merge.entity_copy_observer" value="allow"/>
</properties>
</persistence-unit>
【问题讨论】:
-
你有异常吗?您是否检查了生成的 SQL 语句?此外,您在 Java EE 容器中。您的 DAO 应该是无状态的,而不是单例,因为 EntityManager 不是线程安全的
-
@SimonMartinelli 不,我没有遇到任何异常。我试过了,但在达成这个声明之前还有很多事情要做。因此,即使我启用了日志记录,对于这个特定的合并运行哪个 select 和 update 语句也是模棱两可的。关于 Singleton,我知道它应该是无状态的,我目前无法在获得批准之前进行更改。
-
我遇到了同样的问题,不知道发生了什么以及如何解决它。
-
@Dmitry 经过深入调查和逐行调试,我们发现调用了另一个方法,其中再次调用了 save 但它是在旧数据上,并且它们都在同一个事务块中这就是为什么它会导致上述行为。
标签: java hibernate jpa merge ejb-3.0