Problem with finding and updating by objectId

已查看 401 次
跳至第一个未读帖子

SirenZSL

未读,
2012年9月20日 03:58:122012/9/20
收件人 jongo...@googlegroups.com
Hi

I am new to Jongo and MongoDB and I'm struggling with the updte and find functions by object id. I am getting com.mongodb.util.JSONParseException when trying to either find or update by objectid.

I am using collection.findOne(new ObjectId(id)); where id is a String. I hav tried manye versions of the update - here's one: 
collection.update("{_id:#}", new ObjectId(id), pojo); or collection.update("{_id:#}", new ObjectId(id)).with("{$set:#}", pojo);
The latter gives med: 
Caused by: com.mongodb.util.JSONParseException: 
{_id:{ "$oid" : "505abd173004ccb46be122c8"}}

My pojo looks like this:
public class User {
    
    ObjectId _id;
    String firstName;
    String lastName;
    int userLevel;

    User() {
    }
}

I am using jersey and jackson.

I really appreciate any help or tips.


yves amsellem

未读,
2012年9月20日 04:39:362012/9/20
收件人 jongo...@googlegroups.com
Hello,


Your question is related to this one.
Its answer can be adapted to your needs the followinfg way:

public class Example {
    @Before
    public void setUp() throws UnknownHostException, MongoException {
        DB db = new Mongo("127.0.0.1").getDB("jongo");
        Jongo jongo = new Jongo(db);
        collection = jongo.getCollection("friends");
    }
    @Test
    public void test() {
        Friend friend = new Friend();
        collection.save(friend);
 
        friend.setName("John");
        collection.update("{_id: #}", friend.getId()).with("{$set:#}", friend);

        Friend john = collection.findOne("{name:'John'}").as(Friend.class);
        assertThat(john.getName()).isEqualTo("John");
    }
}
public class Friend {
    private ObjectId _id;
    private String name;
    private String address;
}

yves amsellem

未读,
2012年9月20日 04:43:552012/9/20
收件人 jongo...@googlegroups.com
Hi,


Last thing: are you using the last Jongo version, 0.2?
Does it helps?
--
yves

SirenZSL

未读,
2012年9月20日 05:54:582012/9/20
收件人 jongo...@googlegroups.com
Hei

Thank you for your answer. I still get the same exception. I am using version 0.2 of Jongo. 

/Siren

yves amsellem

未读,
2012年9月20日 06:11:292012/9/20
收件人 jongo...@googlegroups.com
Hi,


This seems odd.

Do you get the same error with the test I provide?
It works with Jongo 0.2 and looks like your needs.

If it fails too, can you provide a full stack trace?
Thanks.

SirenZSL

未读,
2012年9月20日 06:13:382012/9/20
收件人 jongo...@googlegroups.com
I found a "workaround" for this - actually looking at your project, https://github.com/yamsellem/jongo-jersey, and now I am doing a collections.save(pojo) to update the document. Still I would like the update by objectid work.

SirenZSL

未读,
2012年9月20日 07:40:332012/9/20
收件人 jongo...@googlegroups.com

Hi. No the test does not work. Here is the stacktrace:

SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container

java.lang.IllegalArgumentException: Unable to create Update query {_id: #}, please check cause exception. Beware 'update(String query, String modifier)' has been replaced by 'update(String query, Object... parameters)' in v0.2. To specify modifier please use: 'update(String query).with(String modifier)'

at org.jongo.Update.createQuery(Update.java:79)

at org.jongo.Update.<init>(Update.java:39)

at org.jongo.MongoCollection.update(MongoCollection.java:95)

at no.vangenplotz.prodapp.data.Users.get(Users.java:43)

at no.vangenplotz.prodapp.resource.UserResource.get(UserResource.java:37)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)

at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)

at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)

at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)

at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)

at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)

at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)

at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)

at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1480)

at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1411)

at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360)

at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350)

at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)

at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)

at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)

at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)

at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)

at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)

at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)

at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)

at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)

at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)

at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)

at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)

at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)

at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)

at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)

at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)

at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)

at com.sun.grizzly.ContextTask.run(ContextTask.java:71)

at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)

at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)

at java.lang.Thread.run(Thread.java:680)

Caused by: java.lang.IllegalArgumentException: {_id: { "$oid" : "505b000830043a4bf224c0b9"}} cannot be parsed

at org.jongo.query.Query.convertToDBObject(Query.java:33)

at org.jongo.query.Query.<init>(Query.java:26)

at org.jongo.query.QueryFactory.createQuery(QueryFactory.java:40)

at org.jongo.Update.createQuery(Update.java:73)

... 48 more

Caused by: com.mongodb.util.JSONParseException: 

{_id: { "$oid" : "505b000830043a4bf224c0b9"}}

 ^

at com.mongodb.util.JSONParser.parseString(JSON.java:482)

at com.mongodb.util.JSONParser.parseObject(JSON.java:365)

at com.mongodb.util.JSONParser.parse(JSON.java:331)

at com.mongodb.util.JSONParser.parse(JSON.java:281)

at com.mongodb.util.JSON.parse(JSON.java:240)

at com.mongodb.util.JSON.parse(JSON.java:225)

at org.jongo.query.Query.convertToDBObject(Query.java:31)

... 51 more

yves amsellem

未读,
2012年9月20日 08:57:112012/9/20
收件人 jongo...@googlegroups.com
Hi,


The stack trace gives some clues:

Beware 'update(String query, String modifier)' has been replaced by 'update(String query, Object... parameters)' in v0.2. To specify modifier please use: 'update(String query).with(String modifier)'

This means you call the update(String, String) method instead of update(String, Object...).with(String).

My test was wrong, sorry, here is a working version:

@Test
public void test() {
    Friend friend = new Friend();
    collection.save(friend);

    friend.setName("John");
    ObjectId id = friend.getId();
    friend.setId(null);
    collection.update("{_id: #}", id).with("{$set:#}", friend);

    Friend john = collection.findOne("{name:'John'}").as(Friend.class);
    assertThat(john.getName()).isEqualTo("John");
}

Yes, it is a bit strange, but, as a hidden feature (undocumented yet) is has a flow: update().with(modifier) method won't work if the modifier contains the _id of the object.
Maybe Benoît will have a better clue, but for the moment on, it's the way to do.

Jongo 0.3 will clean that up, I promise.

SirenZSL

未读,
2012年9月20日 09:25:082012/9/20
收件人 jongo...@googlegroups.com
Hi again..

The test now works! But.. if I do the exact same thing in my REST service it still fails with the parseException... Its running on glassfish.

yves amsellem

未读,
2012年9月20日 09:40:492012/9/20
收件人 jongo...@googlegroups.com
Hi,


So it seems that the problem is between Jongo and Jersey.
Have you configure properly the Jersey Provider given in this sample?
Be careful, the package of this provider must be on Jersey classpath; either in the web.xml or with a params Map (when used with Guice or similar).
To be sure, you can put a break point into this provider.

What is your test environment? What do you use to call your Jersey web services?
Maybe you can clone the jongo-jersey repository, create a falling test and submit a pull request.
I will be apt to help you super fast if I can properly reproduce your problem ;-).
Thanks.

SirenZSL

未读,
2012年9月20日 09:56:322012/9/20
收件人 jongo...@googlegroups.com
My bad.. It works! I finally got it to work with your previous solution. Thank you so much for all your help and for finding the problem with the test example.

And yes - I am using the Jersey Provider from your sample - works perfectly! :)

/Siren

Benoît GUEROUT

未读,
2012年9月20日 13:54:472012/9/20
收件人 jongo...@googlegroups.com
Hi guys,

So what was the problem ? Deprecated usage of 'update' method and Jersey-Jackson incompatibility ?

Is this topic related ton https://github.com/bguerout/jongo/issues/58 ?

SirenZSL

未读,
2012年9月21日 07:27:282012/9/21
收件人 jongo...@googlegroups.com
Hi

Yes, the last problem I had, I think, was releated to having several version of the mongo-java-driver and jackson in my target folder after doing lots of testing when the first test example didn't work. Cleaning and restarting everything made the fix work in my code as well. 

After getting over this problem I am really enjoying jongo and mongoDB. So much better than doing sql!

yves amsellem

未读,
2012年9月22日 06:11:272012/9/22
收件人 jongo...@googlegroups.com
Hi,


To be complete on the matter, the standard way to update an object is MongoCollection.save() method.
MongoCollection.update().with() is dedicated to partial updating (only a sub-node, etc).

public class Example {
    @Before
    public void setUp() throws UnknownHostException, MongoException {
        DB db = new Mongo("127.0.0.1").getDB("jongo");
        Jongo jongo = new Jongo(db);
        collection = jongo.getCollection("friends");
    }
    @Test
    public void test() {
        Friend friend = new Friend();
        collection.save(friend);
 
        friend.setName("John");
        collection.save(friend);


        Friend john = collection.findOne("{name:'John'}").as(Friend.class);
        assertThat(john.getName()).isEqualTo("John");
    }
}

yves amsellem

未读,
2012年9月22日 06:43:252012/9/22
收件人 jongo...@googlegroups.com
And because this is not straightforward, we will probably add a MongoCollection.update().with(document) method in the next Jongo release.
回复全部
回复作者
转发
0 个新帖子