Well, replying to myself again with some more information...hoope I'm not
getting annoying.

First, I got tripped up writing some tests where I was not saving the
session before testing with queries and was getting some false positives.
This behavior is explained in Sec. 6.6.12 of the JCR spec.

Given the JUnit TestCase pasted at the end of this mail, the
testNullPropertySql test succeeds but the testNullPropertyXPath fails with:

javax.jcr.ItemNotFoundException: foo
   at
org.apache.jackrabbit.core.query.lucene.RowIteratorImpl$RowImpl.getValue(
RowIteratorImpl.java:255)


I've now changed my other tests to no longer use an imported document view,
but this hasn't had any effect -- single-valued STRING custom properties of
my custom node type (which extend nt:file) with no value are still returned
with IS NOT NULL :( So this is appearantly not related to round-tripping
document views.




/*
* Created on Aug 24, 2006
*/
package com.hdna.compass.test.support;

import javax.jcr.Node;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager ;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;

import junit.framework.TestCase;

/**
* JcrNullPropertyTest is a ...
*
* @since 1.0.0
* @version $Id: $
*/
public class JcrNullPropertyTest extends TestCase {

   private Session session;

   private Node testNode1;

   private Node testNode2;

   /*
    * (non-Javadoc)
    *
    * @see junit.framework.TestCase#setUp()
    */
   protected void setUp() throws Exception {
       super.setUp();
       // get session from Spring context
       session = JcrTestSupport.getSession ();
       testNode1 = session.getRootNode().addNode("test1",
"nt:unstructured");
       testNode2 = session.getRootNode().addNode("test2",
"nt:unstructured");
       testNode2.setProperty ("foo", "bar");
       session.save();
       session.refresh(false);
   }

   /*
    * (non-Javadoc)
    *
    * @see junit.framework.TestCase#tearDown()
    */
   protected void tearDown() throws Exception {
       testNode1.remove();
       testNode2.remove();
       session.save();
       session.logout();
       super.tearDown();
   }

   /**
    *
    * @throws Exception
    */
   public void testNullPropertySql() throws Exception {

       QueryManager qmgr = session.getWorkspace().getQueryManager();

       String sql = "SELECT foo FROM nt:unstructured"
               + " WHERE foo IS NOT NULL";

       Query query = qmgr.createQuery(sql, Query.SQL);
       QueryResult queryResult = query.execute();

       for (RowIterator iter = queryResult.getRows (); iter.hasNext();) {
           Row row = iter.nextRow();

           assertNotNull("foo is null", row
                   .getValue("foo"));
       }

   }

   /**
    *
    * @throws Exception
    */
   public void testNullPropertyXPath() throws Exception {

       QueryManager qmgr = session.getWorkspace().getQueryManager();
       String xpath = "//element(*, nt:unstructured)[EMAIL PROTECTED]";

       Query query = qmgr.createQuery(xpath, Query.XPATH);
       QueryResult queryResult = query.execute();

       for (RowIterator iter = queryResult.getRows(); iter.hasNext();) {
           Row row = iter.nextRow();

           assertNotNull("foo is null", row
                   .getValue("foo"));

       }

   }
}

On 8/24/06, Doug Douglass <[EMAIL PROTECTED]> wrote:

Replying for the benefit of others...

Appearantly the export/import of a document view breaks the sql IS NULL/IS
NOT NULL test for optional properties that never had a value assigned, at
least for STRING properties, I haven't tested other types. The Value in a
Row returned in a QueryResult is null, but trying to "SELECT ... WHERE
the:property IS NOT NULL" includes nodes where the:property equals null,
vice versa for IS NULL.

I'll be rethinking my use of document view export/import for setting up a
standard set of data for unit tests.

NOTE: This issue occurs with different persistence managers -- tested with
XMLPersistenceManager and DerbyPersistentManager.


On 8/24/06, Doug Douglass < [EMAIL PROTECTED]> wrote:
>
> Thanks for the reply (and others) Marcel,
>
> I thought #1 should have worked also. I'll write up a test to inspect
> the Row and it's values and see what's actually in there.
>
> Note that the nodes in question are an exported document view that is
> imported during Junit TestCase.setUp and removed again in
> TestCase.tearDown -- sort of a poor mans dbunit for jcr.
>
> Doug
>
>
> On 8/24/06, Marcel Reutegger < [EMAIL PROTECTED]> wrote:
> >
> > Doug Douglass wrote:
> > > I thought I knew the answer but I'm unable to get it right:
> > >
> > >  If a node type baz is defined as having an optional property
> > foo:bar
> > > (STRING), and I want to find all such nodes without a foo:bar
> > property
> > > actually stored (i.e., Node.hasProperty("foo:bar") == false), I
> > would
> > > expect
> > > that one of the following would work:
> > >
> > >  1. SELECT * FROM baz WHERE foo:bar IS NULL;
> >
> > this one should work. there is a test case, which actually tests this
> > feature: SimpleQueryTest.testIsNull ()
> >
> > are you able to reproduce the error when using a predefined node type
> > like nt:unstructured?
> >
> > >  2. SELECT * FROM baz WHERE foo:bar = '';
> >
> > this will return baz nodes with a foo:bar property *set* to an empty
> > string. which is obviously not the same as nodes not having the
> > property at all.
> >
> > regards
> >   marcel
> >
>
>

Reply via email to