ClassCastException: com.mongodb.BasicDBObject cannot be cast to com.mongodb.DBRef

1,644 views
Skip to first unread message

Ian Clarke

unread,
Jul 23, 2010, 10:01:47 AM7/23/10
to mor...@googlegroups.com
Getting the following error, here is EventTrackerTest.java line 33:

final List<PublisherHourlyStats> pubStats = db.datastore.find(PublisherHourlyStats.class).asList();


java.lang.RuntimeException: java.lang.ClassCastException: com.mongodb.BasicDBObject cannot be cast to com.mongodb.DBRef
at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:380)
at com.google.code.morphia.mapping.Mapper.fromDBObject(Mapper.java:213)
at com.google.code.morphia.query.MorphiaIterator.next(MorphiaIterator.java:36)
at com.google.code.morphia.query.QueryImpl.asList(QueryImpl.java:139)
at net.uprizer.engine.events.EventTrackerTest.testBid(EventTrackerTest.java:33) <-- my code
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 org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:580)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:478)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:617)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:885)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:110)
at org.testng.TestRunner.runWorkers(TestRunner.java:712)
at org.testng.TestRunner.privateRun(TestRunner.java:582)
at org.testng.TestRunner.run(TestRunner.java:477)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:324)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:319)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:292)
at org.testng.SuiteRunner.run(SuiteRunner.java:198)
at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:823)
at org.testng.TestNG.runSuitesLocally(TestNG.java:790)
at org.testng.TestNG.run(TestNG.java:708)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:73)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:124)
Caused by: java.lang.ClassCastException: com.mongodb.BasicDBObject cannot be cast to com.mongodb.DBRef
at com.google.code.morphia.mapping.ReferenceMapper.readSingle(ReferenceMapper.java:150)
at com.google.code.morphia.mapping.ReferenceMapper.fromDBObject(ReferenceMapper.java:141)
at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:368)
... 26 more

Any ideas?

Ian.

--
Ian Clarke
CEO, SenseArray
Email: i...@sensearray.com
Ph: +1 512 422 3588

Scott Hernandez

unread,
Jul 23, 2010, 10:17:27 AM7/23/10
to mor...@googlegroups.com
Yes, your data is not correct for your class. Did you store a DBref,
or Key in your update, or a copy of the whole object?

It basically means you have an embedded element, where a reference is
expected. What does your document look like in mongodb?

Ian Clarke

unread,
Jul 23, 2010, 10:26:14 AM7/23/10
to mor...@googlegroups.com
It looks like this:

> db.PublisherHourlyStats.find() 
{ "_id" : ObjectId("4c499ee330825d696e52317c"), "bids" : 1, "d" : 23, "h" : 13, "m" : 7, "pub" : { "_id" : { "floatApprox" : 2 }, "lastMod" : { "floatApprox" : 1279893219761 } }, "y" : 2010 }

Here is the code I use to store it (including the workaround we discussed):

datastore.update(

datastore.createQuery(PublisherHourlyStats.class).field("y").equal(date.getYear()).field("m")

.equal(date.getMonthOfYear()).field("d").equal(date.getDayOfMonth()).field("h")

.equal(date.getHourOfDay()).field("pub").equal(bid.publisher), datastore

.createUpdateOperations(PublisherHourlyStats.class).inc("bids").set("pub", bid.publisher), true);


Is that not correct?

Ian.

Scott Hernandez

unread,
Jul 23, 2010, 11:41:09 AM7/23/10
to mor...@googlegroups.com
On Fri, Jul 23, 2010 at 7:26 AM, Ian Clarke <i...@sensearray.com> wrote:
> It looks like this:
>> db.PublisherHourlyStats.find()
> { "_id" : ObjectId("4c499ee330825d696e52317c"), "bids" : 1, "d" : 23, "h" :
> 13, "m" : 7, "pub" : { "_id" : { "floatApprox" : 2 }, "lastMod" : {
> "floatApprox" : 1279893219761 } }, "y" : 2010 }
> Here is the code I use to store it (including the workaround we discussed):
> datastore.update(
> datastore.createQuery(PublisherHourlyStats.class).field("y").equal(date.getYear()).field("m")
> .equal(date.getMonthOfYear()).field("d").equal(date.getDayOfMonth()).field("h")
> .equal(date.getHourOfDay()).field("pub").equal(bid.publisher), datastore
> .createUpdateOperations(PublisherHourlyStats.class).inc("bids").set("pub",
> bid.publisher), true);
>
> Is that not correct?

Nope, unfortunately the update is storing an embedded element, not a
reference. You need to convert it on your own for the workaround:
ds.getKey(bid.publisher) instead of bid.publisher. In the context of
an update there is no way to know if you mean to store an embedded
element, or a reference to it.

Ian Clarke

unread,
Jul 23, 2010, 11:46:35 AM7/23/10
to mor...@googlegroups.com
On Fri, Jul 23, 2010 at 10:41 AM, Scott Hernandez <scotthe...@gmail.com> wrote:
Nope, unfortunately the update is storing an embedded element, not a
reference. You need to convert it on your own for the workaround:
ds.getKey(bid.publisher) instead of bid.publisher. In the context of
an update there is no way to know if you mean to store an embedded
element, or a reference to it.

Ah, I see.  Hmm, I wish there was a more fluent way to do this type of thing, but I realize its not easy :-/

Ian.
 
Reply all
Reply to author
Forward
0 new messages