首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Modeshape - JCR异常中不可用的会话

Modeshape - JCR异常中不可用的会话
EN

Stack Overflow用户
提问于 2013-10-31 07:07:16
回答 1查看 362关注 0票数 0

有时,当我在一个函数中使用多个Modeshape操作时,我会得到以下错误:

javax.jcr.RepositoryException: ID为'060742fc6‘的会话已关闭,不能再使用。

我在网上找不到任何解释。我称之为:

代码语言:javascript
复制
myFunction( service.doSomething ( service.getStuff ( id, "en_EN" ).getPath() ) );

doSomething,getStuff:

代码语言:javascript
复制
@Interceptors({Foo.class, TraceInterceptor.class})
@Override
public Node doSomething(final String bar) throws RepositoryException {

    return modeshape.execute(new JcrHandler<Node>() {

        @Override
        public Node execute(Session session) throws RepositoryException {
            return session.getNode(bar);
        }
    });
}    

@Interceptors(TraceInterceptor.class)
@Override
public ObjectExtended getStuff(final String query, final String language)
    throws RepositoryException {
    return modeshape.execute(new JcrHandler<ObjectExtended>() {

    @Override
    public ObjectExtendedexecute(Session session) 
        throws RepositoryException {
        QueryManager queryManager = session.getWorkspace().getQueryManager();

        ObjectExtendeditem = null;

        String queryWrapped = 
            "select * from [th:this] as c where name(c)='lang_" 
            + language + "' and c.[th:mylabel] "
                    + "= '" + queryStr + "'";
        LOGGER.debug("Query: " + queryWrapped);
        Query query =
            queryManager.createQuery(queryWrapped,Query.JCR_SQL2);

        QueryResult result = query.execute();
        NodeIterator iter = result.getNodes();
        while (iter.hasNext()) {
            Node node = iter.nextNode().getParent();

            if (node.isNodeType("th:term")) {
                item = new ObjectExtended();
                item.setLabel(getLabel(language, node));
                item.setPath(node.getPath());
            }
        }
        return item;
    }
    });
}

为什么会发生这种事?我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-31 12:05:47

该错误消息意味着两件事之一:要么是存储库被关闭,要么是调用Session.logout()方法。

上面的代码都没有显示您的会话是如何管理的,您也没有说明是否使用框架。但是,我怀疑您在某种程度上占用了一个会话太长时间(可能是在您的框架关闭会话之后),或者会话正在泄漏给多个线程,一个线程试图在另一个线程关闭它之后使用它。

后者可能是一个真正的问题:虽然将单个Session实例从一个线程传递到另一个线程是可以的(只要原始线程不再使用它),但是根据JCR2.0规范,Session实例不是线程安全,不应该被多个线程并发使用。

如果要在代码中创建会话,通常最好使用try-finally块:

代码语言:javascript
复制
Session session = null;
try {
    session = ... // acquire the session
    // use the session, including 0 or more calls to 'save()'
} catch ( RepositoryException e ) {
    // handle it
} finally {
   if ( session != null ) {
       try {
           session.logout();
       } finally {
           session = null;
       }
    }
}

请注意,logout()不抛出RepositoryException,因此上面的表单通常运行良好。当然,如果您知道以后在方法中不使用session,则不需要内部try-finally来使session引用为空:

代码语言:javascript
复制
Session session = null;
try {
    session = ... // acquire the session
    // use the session, including 0 or more calls to 'save()'
} catch ( RepositoryException e ) {
    // handle it
} finally {
   if ( session != null ) session.logout();
}

这种逻辑可以很容易地封装。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19700308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档