aem - javax.jcr.InvalidItemStateException : Item cannot be saved

标签 aem jcr sling jackrabbit

我在单盒 cq5 作者环境中遇到以下异常。

javax.jcr.InvalidItemStateException: Item cannot be saved 
because node property has been modified externally

更多异常详情:

Caused by: javax.jcr.InvalidItemStateException: Unable to update a stale item: item.save()
    at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:262)
    at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
    at org.apache.jackrabbit.core.ItemImpl.perform(ItemImpl.java:91)
    at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:329)
    at org.apache.jackrabbit.core.session.SessionSaveOperation.perform(SessionSaveOperation.java:65)
    at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
    at org.apache.jackrabbit.core.SessionImpl.perform(SessionImpl.java:361)
    at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:812)
    at com.day.crx.core.CRXSessionImpl.save(CRXSessionImpl.java:142)
    at org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider.commit(JcrResourceProvider.java:511)
    ... 215 more
Caused by: org.apache.jackrabbit.core.state.StaleItemStateException: 3bec1cb7-9276-4bed-a24e-0f41bb3cf5b7/{}ssn has been modified externally
    at org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:679)
    at org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate(SharedItemStateManager.java:1507)
    at org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1537)
    at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:400)
    at org.apache.jackrabbit.core.state.XAItemStateManager.update(XAItemStateManager.java:354)
    at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:375)
    at org.apache.jackrabbit.core.state.SessionItemStateManager.update(SessionItemStateManager.java:275)
    at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:258)

这里是代码示例:

adminResourceResolver = resourceResolverFactory
                .getAdministrativeResourceResolver(null);
Resource fundPageResource = adminResourceResolver.getResource(page
                .getPath() + "/jcr:content");
ModifiableValueMap homePageResourceProperties = fundPageResource
                .adaptTo(ModifiableValueMap.class);
homePageResourceProperties.put("ssn",(person.getSsn());

adminResourceResolver.commit();

有什么想法吗?可能有多个线程访问此代码,因为多个页面上的多个作者从创作的组件调用此代码。

谢谢, 斯里

最佳答案

这是您在 CQ5.5 中经常看到的错误(并且随着每个版本的增加而减少)。这个问题的根本原因是多个进程/服务在大致相同的时间跨度内修改相同的资源(通常使用不同的 session ,有时甚至与不同的用户)。

也许可以用一个小例子来证明。 session A 和 B 都引用了资源 X。 session A 修改了 X 的一些属性,保存并提交,然后被销毁。这一切进行得很顺利。 session B 仍然有 A 进行修改之前的情况快照, session B 进行修改并且一切看起来都很好,直到它尝试保存。此时, session B 检测到它无法提交更改,因为它没有最新的节点状态。它检测到一些其他 session 对同一节点进行了更改。本质上,当前节点状态与 session A 所做的修改相冲突,并抛出 ItemStale 异常。此异常的原因是 API 不知道您是要保留 A 所做的更改、保留当前 session 所做的更改并放弃 A 所做的更改,还是合并它们。

此错误经常发生在长时间运行的 session 和工作流/监听器组合中。因此,建议保持 session 尽可能短,以尽可能防止此类冲突。

处理此问题的一种方法是在调用 .save() 之前调用 session.refresh(keepChangesBoolean)。这指示当前 session 检查其他 session 所做的更新并根据您提交的 bool 标志进行处理。然而,这并不能保证,因为仍然有可能在您的刷新和保存调用之间,另一个 session 已经完成了相同的操作。它只会降低发生此异常的几率。 另一种处理方法是从头开始重试。

关于aem - javax.jcr.InvalidItemStateException : Item cannot be saved,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38878394/

相关文章:

jcr - 如何在jcr中获取节点属性的数组值

java - 使用 DateFormat.parse() 无法解析的日期

java - Sling调度器方法重构

maven - 使用参数到 Maven 配置文件

adobe - 如何在 CQ5 中配置声明式服务

java - 如何获取jcr中所有现有的组?

java - 存储库类型

aem - CQ5.5 获取 servlet 中资源的 .infinity.json

osgi - 在 Adob​​e CQ5 中设置属性

aem - 获取 clientlibs 文件的路径