尽管刷新和事务提交, hibernate 实体属性没有被持久化到数据库中

标签 hibernate jpa merge commit

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

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

我已经明确调用了 flushgetTransaction().commit()合并实体后在我的实体管理器上,但仍然没有骰子。

如果我刷新我的页面(可能会得到一个不同的 EntityManager 因为我的 EntityManagers 是对话范围的)然后我可以突然删除我的 MXGroup没有任何问题。

我知道我可以采取一些解决方法 - 所以这在很大程度上是关于为什么会发生这种情况的学术练习......

我的 MXGroup实体通过 ajax 使用以下方法通过 RESTful 接口(interface)加载:(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;
}

userGroupService.getPersonalGroups()方法看起来像:
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;
}
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();
}

mergeMXGroup存在:
@Override
public void mergeMXGroup(MXGroup group) {
    super.merge(group);
}

谁的super实现看起来像:
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。但我会认为刷新和提交会解决问题?事实上,这是我第一次不得不在整个项目中明确刷新/提交......

有什么想法吗?

最佳答案

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

这些情况中的任何一种都可能解释您的问题的原因(或者可能不是):

The semantics of the merge operation applied to an entity X are as follows:

  • If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.
  • If X is a new entity instance, a new managed entity instance X' is created and the state of X is copied into the new managed entity instance X'.
  • If X is a removed entity instance, an IllegalArgumentException will be thrown by the merge operation (or the transaction commit will fail).
  • If X is a managed entity, it is ignored by the merge operation, however, the merge operation is cascaded to entities referenced by relationships from X if these relationships have been annotated with the cascade element value cascade=MERGE or cascade=ALL annotation.
  • If X is an entity merged to X', with a reference to another entity Y, where cascade=MERGE or cascade=ALL is not specified, then navigation of the same association from X' yields a reference to a managed object Y' with the same persistent identity as Y

The persistence provider must not merge fields marked LAZY that have not been fetched: it must ignore such fields when merging.

关于尽管刷新和事务提交, hibernate 实体属性没有被持久化到数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33297380/

相关文章:

java - HQL 或 SQL 查询从许多相关实体获取数据

java - 使用 spring jpa 编写 group by 表达式

java - 调用 persist() 时 : "uninitialized proxy passed to persist()"

javascript - JS动态更改表中的数据

java - Hibernate 为列设置 null 值,而不是在 saveOrUpdate() 上删除整行

mysql - 12 :00:00 stored as 00:00:00 in MySql when TemporalType. 通过 Hibernate 使用时间

java - Eclipse Luna - Jboss 7 Servlet 和 JPA 应用程序 servlet 无法启动

python - 打开元素包装并添加新元素

python - 合并两个具有时间戳和队列长度的元组列表

mysql - 通信链接失败时Grails重新连接到mysql