1

I'm trying to read data that has been saved in MongoDB and de-serialise it back into a POJO, using Jackson/Jongo. This works fine when the fields do not contain a hash. When the fields include a hash, Jongo thinks this is a placeholder so expects another object to replace it.

For example.. Person ed = collection.findOne("{name:\"ed\"}").as(Person.class); .. works fine.

However.. Sale s = collection.findOne("{orderRef:\"#1000\"}").as(Sale.class); .. does not work.

I've tried passing in a hash as an argument, but this still fails. For example: Sale s = collection.findOne("{orderRef:\"#1000\"}", "#").as(Sale.class);

Has anyone else had any experience with this problem? Any assistance would be a great help!

Thanks,

Ed

Stennie
  • 63,885
  • 14
  • 149
  • 175
user3812127
  • 75
  • 1
  • 4

2 Answers2

2

If you'd like to find an order reference with #1000 value, try something like this :

Sale s = collection.findOne("{orderRef:#}", "#1000").as(Sale.class);

The # character happens to be a placeholder for the variable values. Jongo has a built-in templating system, which will do basic query sanitization for you. This templating system will scan the query string for # character, and replace it with the sanitized version of the parameters you put behind them. Since in your case the # is in the field value, not the field name, you don't need any special processing. Here's a more expanded example of how it works.

public class JongoTest {

    public static void main(String[] args) throws Exception {

        // initialize mongo
        MongoClient mongoClient = new MongoClient("localhost", 27017);
        DB db = mongoClient.getDB("test");
        Jongo jongo = new Jongo(db);

        // create a simple object here
        Map<String, Object> pojo = new LinkedHashMap<>();
        pojo.put("artist", "The Chainsmokers");
        pojo.put("title", "#selfie");
        pojo.put("timestamp", System.currentTimeMillis());

        // save the result in the system
        jongo.getCollection("test").save(pojo);

        // perform query and print the result
        Iterable<Object> iterator = jongo.getCollection("test").find("{title:#}", "#selfie").as(Object.class);
        for (Object dbResult : iterator) {
            System.err.println(dbResult.toString());
        }
    }

}

Hope this helps.

xvronny
  • 84
  • 5
  • Thanks for the reply. Replacing `Sale s = collection.findOne("{orderRef:\"#1000\"}", "#").as(Sale.class);` with `Sale s = collection.findOne("{orderRef:#}", "#1000").as(Sale.class);` worked a treat! – user3812127 Jul 22 '14 at 09:39
0

I haven't experienced this problem and I've only heard of having to escape dollar signs and periods in keys... but you could URI-encode/decode any attribute values that might contain a # character:

String value = "#1000";
String orderRef = String.format("{orderRef: \"%s\"}", URLEncoder.encode(value, "UTF-8"));

You don't want to encode the whole JSON string because this would encode the important JSON syntax bits such as brackets and colons.

Decoding is very similar:

String encodedOrderRefValue = "%231000";
String decoded = URLDecoder.decode(encodedOrderRefValue, "UTF-8"); // returns "#1000"
Erik Gillespie
  • 3,929
  • 2
  • 31
  • 48