Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA合并在第一次不起作用,但在第二次起作用_Java_Hibernate_Jpa_Merge_Ejb 3.0 - Fatal编程技术网

Java JPA合并在第一次不起作用,但在第二次起作用

Java JPA合并在第一次不起作用,但在第二次起作用,java,hibernate,jpa,merge,ejb-3.0,Java,Hibernate,Jpa,Merge,Ejb 3.0,我知道这是很常见的,并且有很多关于合并而不是更新数据库中数据的问题。但这有点不同 从前端,当我点击save按钮时,我可以看到CaseSample中的数据为所有三个属性更新,但当对该对象调用merge时,它不会更新DB。在返回响应之后,如果我再次单击save按钮,因为字段中有我想要的数据,那么在再次调用CaseSample对象上的merge之后,这次它将数据保存在数据库中 这种情况只发生在一种样本类型上。 假设我们有两个样本类型A和B与案例c相对。 如果我更新类型A中的值并单击“保存”,它将更新数

我知道这是很常见的,并且有很多关于合并而不是更新数据库中数据的问题。但这有点不同

从前端,当我点击save按钮时,我可以看到CaseSample中的数据为所有三个属性更新,但当对该对象调用merge时,它不会更新DB。在返回响应之后,如果我再次单击save按钮,因为字段中有我想要的数据,那么在再次调用CaseSample对象上的merge之后,这次它将数据保存在数据库中

这种情况只发生在一种样本类型上。 假设我们有两个样本类型A和B与案例c相对。 如果我更新类型A中的值并单击“保存”,它将更新数据库中的数据。但是,如果我对类型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
}
控制器:

 for (CaseSpecimen specimen : case.getCaseSpecimens()) {
    ... if the updated object from front end the below line will execute
    caseSpecimensUpdatedList.add(caseService.updateCaseSpecimen(specimen));
}
案例服务:目前它是一个额外的层。这只是调用Dao方法。

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>

java:jboss/datasources/AppDataSource

如果您阅读merge的文档,您会发现:

将给定实体的状态合并到当前持久性上下文中

这并不意味着数据库将立即更新!持久性上下文充当事务性写后缓存,对任何实体状态更改进行排队。和任何写后缓存一样,更改首先应用于内存中,并在刷新期间与数据库同步。flush操作接受每个实体状态更改,并将其转换为INSERT、UPDATE或DELETE语句

事实上,flush文档说明:

将持久性上下文同步到基础数据库

在当前事务中,这显然是正确的。在事务提交之前,没有可见的更改

如果未显式调用刷新,则持久性提供程序将遵循可能具有不同设置的策略:自动或提交

同样,FlushModType的文档说明:

在事务中执行查询时,如果在 查询或TypedQuery对象,或者如果持久性上下文的刷新模式设置为“自动”(默认),并且尚未为查询或TypedQuery对象指定刷新模式设置,持久性提供程序负责确保持久性上下文中所有实体状态的所有更新对查询处理可见,这些更新可能会影响查询结果。持久性提供者实现可以通过将这些实体刷新到数据库或通过一些其他方式来实现这一点

如果设置了FlushModeType.COMMIT,则未指定对持久性上下文中的实体进行的更新对查询的影响


如果您阅读merge的文档,您会发现:

将给定实体的状态合并到当前持久性上下文中

这并不意味着数据库将立即更新!持久性上下文充当事务性写后缓存,对任何实体状态更改进行排队。和任何写后缓存一样,更改首先应用于内存中,并在刷新期间与数据库同步。flush操作接受每个实体状态更改,并将其转换为INSERT、UPDATE或DELETE语句

事实上,flush文档说明:

将持久性上下文同步到基础数据库

在当前事务中,这显然是正确的。在事务提交之前,没有可见的更改

如果未显式调用刷新,则持久性提供程序将遵循可能具有不同设置的策略:自动或提交

同样,FlushModType的文档说明:

在事务中执行查询时,如果在 查询或TypedQuery对象,或者如果持久性上下文的刷新模式设置为“自动”(默认),并且尚未为查询或TypedQuery对象指定刷新模式设置,持久性提供程序负责确保持久性上下文中所有实体状态的所有更新对查询处理可见,这些更新可能会影响查询结果。持久性提供者实现可以通过将这些实体刷新到数据库或通过一些其他方式来实现这一点

如果设置了FlushModeType.COMMIT,则未指定对持久性上下文中的实体进行的更新对查询的影响


你有例外吗?您是否检查了生成的SQL语句?此外,您位于JavaEE容器中。您的DAO应该是无状态的,而不是单一的,因为EntityManager不是线程safe@SimonMartinelli不,我没有任何例外。我试过了,但在达成这一声明之前还有很多事情要做。所以,即使我启用了日志记录,对于这个特定的合并运行哪个select和update语句也是不明确的。关于Singleton,我知道它应该是无状态的,在获得批准之前,我目前不能进行更改。你有例外吗?您是否检查了生成的SQL语句?此外,您位于JavaEE容器中。您的DAO应该是无状态的,而不是单一的,因为EntityManager不是线程safe@SimonMartinelli不,我没有任何例外。我试过了,但在达成这一声明之前还有很多事情要做。所以,即使我启用了日志记录,对于这个特定的合并运行哪个select和update语句也是不明确的。关于Singleton,我知道它应该是无状态的,在获得批准之前,我目前无法进行更改。我已经更新了问题。
  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));
}
<?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>