Uploaded image for project: 'ModeShape'
  1. ModeShape
  2. MODE-2490

NullPointerException when executing queries with order by two nullable fields

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: 4.3.0.Final
    • Fix Version/s: 4.4.0.Final
    • Component/s: JCR, Query
    • Labels:
      None
    • Steps to Reproduce:
      Hide

      As requested, code that reproduces the problem

      class Execute {
      
          public static void main(args: String[]) throws Exception {
              Session session = getSession();
              prepareRepository(session);
      
              createNode(new MyValueObject("1", "A", "Title A", new Date()), session);
              createNode(new MyValueObject("2", "B", null, new Date()), session);
              createNode(new MyValueObject("3", "B", "Title B", new Date()), session);
              createNode(new MyValueObject("4", "C", "Title C", new Date()), session);
              session.save();
              session.logout();
      
              Session session2 = getSession();
              javax.jcr.query.Query query = session2.getWorkspace().getQueryManager().createQuery("select * from [namespace:mymixin] as m WHERE m.type = 'B' ORDER BY m.title ASC, m.created ASC", javax.jcr.query.Query.JCR_SQL2);
              QueryResult queryResult = query.execute();
              System.out.println(queryResult.getRows().getSize());
              session2.logout();
          }
      
          private static void prepareRepository(Session session) throws RepositoryException {
              session.getWorkspace().getNamespaceRegistry().registerNamespace("namespace", "http://blah.com/blah/blah");
              NodeTypeManager manager= session.getWorkspace().getNodeTypeManager();
              NodeTypeTemplate template = manager.createNodeTypeTemplate();
              template.setName("namespace:mymixin");
              template.setQueryable(true);
              template.setAbstract(false);
              template.setMixin(true);
              manager.registerNodeType(template, false);
          }
      
          private static Node createNode(MyValueObject vo, Session session) throws RepositoryException {
      
              final Node node;
              node = session.getRootNode().addNode(vo.getId());
              node.addMixin("namespace:mymixin");
              node.setProperty("type", vo.getType());
      
              Calendar cal = Calendar.getInstance();
              cal.setTime(vo.getDate());
              node.setProperty("created", cal);
      
              node.setProperty("title", vo.getTitle());
              return node;
          }
          
          private static Session getSession() /// Create new jcr session. 
      
          static class MyValueObject {
              private final String id;
      
              private final String type;
      
              private final String title;
      
              private final Date date;
      
              public MyValueObject(String id, String type, String title, Date date) {
                  this.id = id;
                  this.type = type;
                  this.title = title;
                  this.date = date;
              }
      
              public String getId() {
                  return id;
              }
      
              public String getType() {
                  return type;
              }
      
              public String getTitle() {
                  return title;
              }
      
              public Date getDate() {
                  return date;
              }
          }
      }
      
      Show
      As requested, code that reproduces the problem class Execute { public static void main(args: String []) throws Exception { Session session = getSession(); prepareRepository(session); createNode( new MyValueObject( "1" , "A" , "Title A" , new Date()), session); createNode( new MyValueObject( "2" , "B" , null , new Date()), session); createNode( new MyValueObject( "3" , "B" , "Title B" , new Date()), session); createNode( new MyValueObject( "4" , "C" , "Title C" , new Date()), session); session.save(); session.logout(); Session session2 = getSession(); javax.jcr.query.Query query = session2.getWorkspace().getQueryManager().createQuery( "select * from [namespace:mymixin] as m WHERE m.type = 'B' ORDER BY m.title ASC, m.created ASC" , javax.jcr.query.Query.JCR_SQL2); QueryResult queryResult = query.execute(); System .out.println(queryResult.getRows().getSize()); session2.logout(); } private static void prepareRepository(Session session) throws RepositoryException { session.getWorkspace().getNamespaceRegistry().registerNamespace( "namespace" , "http: //blah.com/blah/blah" ); NodeTypeManager manager= session.getWorkspace().getNodeTypeManager(); NodeTypeTemplate template = manager.createNodeTypeTemplate(); template.setName( "namespace:mymixin" ); template.setQueryable( true ); template.setAbstract( false ); template.setMixin( true ); manager.registerNodeType(template, false ); } private static Node createNode(MyValueObject vo, Session session) throws RepositoryException { final Node node; node = session.getRootNode().addNode(vo.getId()); node.addMixin( "namespace:mymixin" ); node.setProperty( "type" , vo.getType()); Calendar cal = Calendar.getInstance(); cal.setTime(vo.getDate()); node.setProperty( "created" , cal); node.setProperty( "title" , vo.getTitle()); return node; } private static Session getSession() /// Create new jcr session. static class MyValueObject { private final String id; private final String type; private final String title; private final Date date; public MyValueObject( String id, String type, String title, Date date) { this .id = id; this .type = type; this .title = title; this .date = date; } public String getId() { return id; } public String getType() { return type; } public String getTitle() { return title; } public Date getDate() { return date; } } }

      Description

      The following query causes a NullPointerException if one of the fields field1 or field2 holds a null value. Problem disappears when one of the fields is removed from order by clause.

      SELECT * FROM [scheme:type] AS t ORDER BY t.field1 ASC, t.field2 ASC
      
      java.lang.NullPointerException
      	at org.mapdb.DataOutput2.writeUTF(DataOutput2.java:147)
      	at org.mapdb.Serializer$1.serialize(Serializer.java:70)
      	at org.mapdb.Serializer$1.serialize(Serializer.java:67)
      	at org.modeshape.jcr.query.Tuples$Tuple2Serializer.serialize(Tuples.java:257)
      	at org.modeshape.jcr.query.Tuples$Tuple2Serializer.serialize(Tuples.java:238)
      	at org.modeshape.jcr.index.local.MapDB$UniqueKeyBTreeSerializer.serialize(MapDB.java:434)
      	at org.mapdb.BTreeMap$NodeSerializer.serialize(BTreeMap.java:385)
      	at org.mapdb.BTreeMap$NodeSerializer.serialize(BTreeMap.java:288)
      	at org.mapdb.Store.serialize(Store.java:154)
      	at org.mapdb.StoreWAL.update(StoreWAL.java:403)
      	at org.mapdb.Caches$HashTable.update(Caches.java:269)
      	at org.mapdb.BTreeMap.put2(BTreeMap.java:746)
      	at org.mapdb.BTreeMap.put(BTreeMap.java:643)
      	at org.modeshape.jcr.query.BufferManager$CloseableSortingBufferWithDuplicates.put(BufferManager.java:698)
      	at org.modeshape.jcr.query.BufferManager$CloseableSortingBufferWithDuplicates.put(BufferManager.java:673)
      	at org.modeshape.jcr.query.engine.process.BufferingSequence.loadAll(BufferingSequence.java:131)
      	at org.modeshape.jcr.query.engine.process.SortingSequence.initialize(SortingSequence.java:81)
      	at org.modeshape.jcr.query.engine.process.SortingSequence.nextBatch(SortingSequence.java:67)
      	at org.modeshape.jcr.query.NodeSequence$6.nextBatch(NodeSequence.java:672)
      	at org.modeshape.jcr.query.engine.process.DelegatingSequence.nextBatch(DelegatingSequence.java:48)
      	at org.modeshape.jcr.query.engine.process.SecureSequence.nextBatch(SecureSequence.java:46)
      	at org.modeshape.jcr.query.engine.process.RestartableSequence$1.nextBatch(RestartableSequence.java:84)
      	at org.modeshape.jcr.query.engine.process.RestartableSequence.nextBatch(RestartableSequence.java:119)
      	at org.modeshape.jcr.query.JcrQueryResult$QueryResultIterator.findNextBatch(JcrQueryResult.java:257)
      	at org.modeshape.jcr.query.JcrQueryResult$QueryResultIterator.hasNext(JcrQueryResult.java:241)
      
      

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                seveneves Ivan Stanislavciuc
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: