Hi all, To share the solution with the rest, it turned out that because the non-standard DataSourcePersistenceManager (see below) swallowed any SQLException that occurred during the determination of whether an item exists, was the cause that the ItemStateManager had an invalid state. By tweaking the code so that SQLExceptions are wrapped inside an ItemStateException and rethrowing the new exceptions everything worked like a charm.
The guys from magnolia have been informed and they're going to include this patch in upcoming releases of the DataSourcePersistenceManager... Thanks for your help! Raymond -----Original Message----- From: Raymond Brandon [mailto:[EMAIL PROTECTED] Sent: Tuesday, July 31, 2007 10:57 To: [email protected] Subject: RE: Jackrabbit reconnect issues Hi Stefan, Thanks but that doesn't work either. In both cases (network cable in place and unpluggend) I get the same ItemNotFoundException. I found out that we're using some non-standard DatabaseManager which offers connection pooling (http://www.magnolia.info/wiki/Wiki.jsp?page=DataSourcePersistenceManage r) and after looking at the code we saw that SQLExceptions are swallowed instead of wrapping them in a ItemStateException and re-throwing them. This could explain the behavior that I'm seeing. I might know more after tweaking that code a bit... Raymond -----Original Message----- From: Stefan Guggisberg [mailto:[EMAIL PROTECTED] Sent: Monday, July 30, 2007 17:33 To: [email protected] Subject: Re: Jackrabbit reconnect issues hi raymond, On 7/30/07, Raymond Brandon <[EMAIL PROTECTED]> wrote: > Hi all, > > I have the following problem: in a web application that gets some of > it's content from jackrabbit, I have to implement a monitor process that > periodically checks whether the JCR is still alive and usable by the > application. > > I'm testing locally on tomcat 5.0 that hosts my web application which > uses a remote Oracle database for a part of its data and a JCR which is > configured to also use a remote Oracle database for a different part of > its data. My use case is to unplug my network cable to simulate losing a > connection. > > I thought that if I tried to retrieve some content that is also used by > the application I would get an indication whether the JCR is able to > retrieve it or not, but it turns out not to be a good choice. The JCR > caches the information that is retrieved, so if my network cable is in > place and I access the JCR for some node path containing some content > and it is retrieved successfully, unplugging the network cable and > trying to retrieve the same content again will also succeed. > > I than had the idea to create a dummy node if it was not already present > in the JCR or delete it if it wasn't. Similar to the previous attempt, I > use the Spring JcrTemplate in which I use the JcrCallback interface to > execute these actions. When the network cable is in place, everything > works ok (of course). When I unplug, I get the desired behavior that > calling save() on the session fails after creating a dummy node > underneath the root. But, when I reconnect my network cable, the JCR > does not seem to recover from the previous error and throws a > javax.jcr.ItemNotFoundException for UUID of the dummy node that was > created in a previous run (see stacktrace). The JCR seems to keep state > somewhere, which is logical since I get the Session from the same > sessionfactory in Spring eveytime... strange; i'd say that calling 'session.refresh(false)' should clear any pendant transient session state... anyway, you could try something like this: boolean checkBackendSanity(Session session) { try { session.getNodeByUUID(UUID.randomUUID().toString()); } catch (ItemNotFoundException e) { // expected return true; } catch (RepositoryException e) { // something's wrong... return false; } } cheers stefan > > Caused by: javax.jcr.ItemNotFoundException: > 33d0f734-2ad7-4097-a3b2-fd349d0b0ba2 > at > org.apache.jackrabbit.core.ItemManager.createItemInstance(ItemManager.ja > va:467) > at > org.apache.jackrabbit.core.ItemManager.getItem(ItemManager.java:323) > at > org.apache.jackrabbit.core.NodeImpl.internalAddChildNode(NodeImpl.java:7 > 96) > at > org.apache.jackrabbit.core.NodeImpl.internalAddNode(NodeImpl.java:740) > at > org.apache.jackrabbit.core.NodeImpl.internalAddNode(NodeImpl.java:687) > at > org.apache.jackrabbit.core.NodeImpl.addNode(NodeImpl.java:1912) > .... > .... > > I'm using JCR version 1.2.1, java 1.4.2, Oracle 9.2.1 > > Does anybody have an idea on how to tackle this properly? > > Raymond > > The code: > > result = (Boolean) template.execute(new JcrCallback() { > public Object doInJcr(final Session session) throws > RepositoryException { > Boolean success = Boolean.FALSE; > Node rootNode = session.getRootNode(); > try { > createDummyNode(rootNode); > session.save(); > success = Boolean.TRUE; > } catch (RepositoryException e) { > // Rollback any changes > session.refresh(false); > throw e; > } finally { > session.logout(); > } > return result; > } > }); > > private void createDummyNode(Node rootNode) throws RepositoryException { > boolean hasNode = false; > try { > hasNode = rootNode.hasNode("dummy"); > } catch (RepositoryException e) {} > if (hasNode) { > Node dummyNode = rootNode.getNode("dummy"); > dummyNode.remove(); > } else { > rootNode.addNode(("dummy"); > } > } > > Spring config: > > <bean id="jcrTemplate" class="org.springmodules.jcr.JcrTemplate"> > <property name="sessionFactory" ref="jcrSessionFactory" /> > <property name="allowCreate" value="true" /> > </bean> > > <bean id="jcrRepository" > class="nl.anwb.autoportaal.dao.jackrabbit.RepositoryFactoryBean"> > <property name="configuration" > value="classpath:jcr-repo-jndi.xml"/> > <property name="repositoryHome" > value="data/jackrabbit-repository"/> > </bean> > > <bean id="jcrSessionFactory" > class="org.springmodules.jcr.JcrSessionFactory"> > <property name="repository" ref="jcrRepository" /> > <property name="credentials" ref="credentials"/> > </bean> > > <bean id="credentials" class="javax.jcr.SimpleCredentials"> > <constructor-arg index="0" value="bogus"/> > <constructor-arg index="1"> > <bean factory-bean="password" factory-method="toCharArray"/> > > </constructor-arg> > </bean> > > <bean id="password" class="java.lang.String"> > <constructor-arg index="0" value="somepassword"/> > </bean> >
