Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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
Hibernate实体属性未持久化到数据库,尽管刷新和事务提交_Hibernate_Jpa_Merge_Commit - Fatal编程技术网

Hibernate实体属性未持久化到数据库,尽管刷新和事务提交

Hibernate实体属性未持久化到数据库,尽管刷新和事务提交,hibernate,jpa,merge,commit,Hibernate,Jpa,Merge,Commit,我有一个实体MXGroup,它可以通过status属性在逻辑上删除。 该实体通过Hibernate持久化到MySQL数据库中。 当我通过JSF页面创建该实体时,将其持久化,然后尝试更新该实体的状态列,而不在创建和逻辑删除之间重新加载页面,对状态列的更改不会持久化 实体显然在Hibernate的缓存和数据库中。更新属性,然后调用merge,不会将更改合并到数据库中 合并实体后,我在实体管理器上显式调用了flush和getTransaction().commit(),但仍然没有骰子 如果我刷新我的页

我有一个实体
MXGroup
,它可以通过
status
属性在逻辑上删除。 该实体通过Hibernate持久化到MySQL数据库中。 当我通过JSF页面创建该实体时,将其持久化,然后尝试更新该实体的
状态
列,而不在创建和逻辑删除之间重新加载页面,对状态列的更改不会持久化

实体显然在Hibernate的缓存和数据库中。更新属性,然后调用
merge
,不会将更改合并到数据库中

合并实体后,我在实体管理器上显式调用了
flush
getTransaction().commit()
,但仍然没有骰子

如果我刷新我的页面(可能会得到一个不同的
EntityManager
,因为我的
EntityManager
属于对话范围),那么我可以突然删除我的
MXGroup
,而不会出现任何问题

我知道我可以做一些变通办法,所以这主要是一个关于为什么会发生这种情况的学术练习

My
MXGroup
实体通过ajax通过RESTful接口加载,方法如下:(PersonalGroup实体扩展MXGroup实体)

getCommonPredicates
在这种情况下,仅在
status==1

删除功能如下所示:

public void deletePersonalGroup() throws BadLoginNameException, UniqueUserLoginException {
    String groupIdStr = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("groupId");
    int groupId = Integer.parseInt(groupIdStr);
    MXGroup group = this.userGroupService.findMXGroup(groupId);

    group.setStatus(0);
    this.userGroupService.mergeMXGroup(group);
    this.userGroupService.forceCommit();
}
protected <T> T merge(T entity) {
    if (canUseService() && beforeMergeEntity(entity)) {
        T merge = this.getEntityManager().merge(entity);
        return merge;
    }
    return null;
}
mergeMXGroup
为:

@Override
public void mergeMXGroup(MXGroup group) {
    super.merge(group);
}
super
实现如下所示:

public void deletePersonalGroup() throws BadLoginNameException, UniqueUserLoginException {
    String groupIdStr = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("groupId");
    int groupId = Integer.parseInt(groupIdStr);
    MXGroup group = this.userGroupService.findMXGroup(groupId);

    group.setStatus(0);
    this.userGroupService.mergeMXGroup(group);
    this.userGroupService.forceCommit();
}
protected <T> T merge(T entity) {
    if (canUseService() && beforeMergeEntity(entity)) {
        T merge = this.getEntityManager().merge(entity);
        return merge;
    }
    return null;
}
RESTful接口几乎肯定会有一个与delete代码不同的实体管理器,因为delete代码是CDI管理的,RESTful接口是EJB。但我原以为同花顺和承诺就能解决这个问题?事实上,这是我第一次在整个项目中显式地刷新/提交


有什么想法吗?

我正在查看有关合并操作语义的规范

这些场景中的任何一个都可能解释问题的原因(或者可能不是):

应用于实体X的合并操作的语义如下 如下:

  • 如果X是分离的实体,则X的状态将复制到具有相同标识的预先存在的托管实体实例X'或新实例X'上 已创建X的托管副本X'
  • 如果X是一个新的实体实例,则会创建一个新的托管实体实例X',并将X的状态复制到新的托管实体实例X'中
  • 如果X是已删除的实体实例,则合并操作将引发IllegalArgumentException(或者事务提交将失败)。
  • 如果X是托管实体,则合并操作将忽略该实体,但是,如果已使用级联元素值cascade=merge或cascade=ALL注释对这些关系进行了注释,则合并操作将级联到由X中的关系引用的实体。
  • 如果X是一个合并到X'的实体,并且引用了另一个实体Y,其中未指定cascade=MERGE或cascade=ALL,则从X'导航同一关联将产生对托管对象Y'的引用,该对象Y'具有与Y相同的持久标识
持久性提供程序不得合并标记为惰性的未提取字段:合并时必须忽略这些字段。


我很确定,这不是问题的解决方案,但我必须补充一点,您的forceCommit()的工作顺序是错误的


首先必须使用flush()写入数据库,然后提交事务。(也就是说,如果您需要刷新。)

您的
@Override
mergeMXGroup
方法不会返回托管实体。尝试返回托管实例,并在JSF/CDIBean中交换它,当它通过EL连接到view时。感谢@Geinmachi没有发现这一点,但不相信它会停止数据在数据库中的持久化,是吗?
public void forceCommit() {
    this.getEntityManager().getTransaction().commit();
    this.getEntityManager().flush();
}