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

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

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

如果刷新页面(可能因为对话范围限制而获得了另一个EntityManager),那么我可以突然删除自己的EntityManagers,而不会出现任何问题。

我知道我可以采取一些解决方法-所以这主要是关于为什么发生这种情况的学术研究...

我的MXGroup实体是通过RESTful接口(interface)通过ajax通过以下方法加载的:(PersonalGroup实体扩展了MXGroup实体)

@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("personal/")
public Response restPersonalGroups() {
    return Response.ok().entity(serializePersonalGroups()).build();
}

public String serializePersonalGroups() {
    final List<PersonalGroup> personalGroupsList = this.userGroupService.getPersonalGroups();
    String personalGroups = serializeGroupList(personalGroupsList);
    return personalGroups;
}

使用MXGroup方法看起来像:
public List<PersonalGroup> getPersonalGroups() {
    CriteriaBuilder builder = this.getEntityManager().getCriteriaBuilder();
    CriteriaQuery<PersonalGroup> criteria = builder.createQuery(PersonalGroup.class);
    Root<PersonalGroup> root = criteria.from(PersonalGroup.class);

    List<Predicate> predicateList = new ArrayList<Predicate>();
    predicateList.addAll(Arrays.asList(getCommonPredicates(PersonalGroup.class, builder, criteria, root)));
    predicateList.add(builder.equal(root.get(PersonalGroup_.user), getUser()));

    TypedQuery<PersonalGroup> query = this.getEntityManager().createQuery(
        criteria.select(root)
            .where(predicateList.toArray(new Predicate[predicateList.size()]))
            .orderBy(builder.asc(root.get(MXGroup_.name)))
            .distinct(true));

    List<PersonalGroup> personalGroups = query.getResultList();
    for (PersonalGroup pg : personalGroups) {
        this.getEntityManager().refresh(pg);
    }
    return personalGroups;
}

在这种情况下,userGroupService.getPersonalGroups()仅添加谓词,以检查getCommonPredicates是否

删除功能如下所示:
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();
}
status == 1为:
@Override
public void mergeMXGroup(MXGroup group) {
    super.merge(group);
}

mergeMXGroup实现如下所示:
protected <T> T merge(T entity) {
    if (canUseService() && beforeMergeEntity(entity)) {
        T merge = this.getEntityManager().merge(entity);
        return merge;
    }
    return null;
}

最后,我强制进行刷新和提交,如下所示:
public void forceCommit() {
    this.getEntityManager().getTransaction().commit();
    this.getEntityManager().flush();
}

RESTful接口(interface)几乎可以肯定具有与删除代码不同的实体管理器,因为删除代码是CDI管理的,而RESTful接口(interface)是EJB。但是我会认为flush和commit会解决问题吗?实际上,这是我第一次必须在整个项目中显式刷新/提交...

有什么想法吗?

最佳答案

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

这些情况之一可能可以解释您的问题的原因(或可能不是):

关于尽管刷新和事务提交,但Hibernate实体属性仍未保留到数据库中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33297380/

10-14 15:31
查看更多