java - Modeshape 中的 session 不可用 - JCR 异常

标签 java session jboss jcr modeshape

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

javax.jcr.RepositoryException: The session with an ID of '060742fc6' has been closed and can no longer be used.

我在网上找不到任何对此的解释。这就是我所说的:

myFunction( service.doSomething ( service.getStuff ( id, "en_EN" ).getPath() ) );

做一些事情,获取东西:

@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;
    }
    });
}

请问为什么会出现这种情况?我做错了什么?

最佳答案

该错误消息意味着以下两种情况之一:存储库正在关闭,或者正在调用 Session.logout() 方法。

以上代码都没有显示您的 session 是如何管理的,并且您没有说明您是否正在使用框架。但我怀疑不知何故,您持有 session 的时间太长(可能是在您的框架关闭 session 之后),或者 session 泄漏到多个线程,并且一个线程在另一个线程关闭它后试图使用它。

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

如果您在代码中创建 session ,通常最好使用 try-finally block :

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引用:

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();
}

这种逻辑很容易被封装。

关于java - Modeshape 中的 session 不可用 - JCR 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19700308/

相关文章:

java - 这个功能是如何使用的?

java - 打印错误

linux - Android 上的 Ubuntu 在 chroot 下报告不同数量的处理器

java - Hibernate session 关闭已关闭

PHP session 不工作

java - 使用 J2EE 和 Jboss 每次测试后回滚

java - JIRA TOMCAT6 查找我的 .JAR :(

spring - 测试 Spring Scope 是否处于事件状态

java - 在 JBoss + Hibernate 中防止事务回滚

spring - 从 JBoss EAP 6.1 中排除 JPA 子系统 - 尝试在 JBoss EAP 6.1 中使用 JPA 2.1