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

4,091 views
Skip to first unread message

Christos L.

unread,
Jan 4, 2012, 2:04:28 PM1/4/12
to Morphia
Hello everyone,
The following error appears when I try to execute query.asList()
(same thing when I try with an Iterator) :


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:
154)
at
com.google.code.morphia.mapping.ReferenceMapper.fromDBObject(ReferenceMapper.java:
145)
at com.google.code.morphia.mapping.Mapper.readMappedField(Mapper.java:
501)
at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:480)
... 14 more


Here's the code snippet generating the error :

final Query<AddressCity> query = ds.find(AddressCity.class);
final AddressDepartment addressDep = new AddressDepartment();
addressDep.setId(new ObjectId("4ef315c46f46c52f3373c904"));
query.field("department").equal(addressDep);
query.order("name");
query.asList();


And here are the concerned classes :

AddressCity :
@Id private ObjectId id;
@Reference private AddressDepartment department;
private String postCode;
private String name;

AddressDepartment :
@Id private ObjectId id;
@Reference private AddressArea area;
@Reference private AddressCountry country;
private String code;
private String name;


I don't understand what I'm doing wrong and this drives me nuts :(

By the way, here's the generated query by morphia :
{ "department" : { "$ref" : "AddressDepartment" , "$id" : { "$oid" :
"4ef315c46f46c52f3373c904"}}}

When I try to execute this on the mongodb shell :
db.AddressCity.find({ "department" : { "$ref" : "AddressDepartment" ,
"$id" : { "$oid" : "4ef315c46f46c52f3373c904"}}}).limit(1);
nothing happens !

However, if I change the query like this :
db.AddressCity.find({ "department" : { "$ref" : "AddressDepartment",
"$id" : ObjectId("4ef315c46f46c52f3373c904")}}).limit(1);
than it works fine... I have this output :

{ "_id" : ObjectId("4ef318836f46b09013f70c85"), "className" :
"com.mycompany.myapp.model.AddressCity", "department" : {
"$ref" : "AddressDepartment",
"$id" : ObjectId("4ef315c46f46c52f3373c904")
}, "name" : "Cityname", "postCode" : "59265" }


Any help on this would be really appreciated !!

Siddhartha Kasivajhula

unread,
Jan 4, 2012, 2:13:23 PM1/4/12
to mor...@googlegroups.com
I struggled with a very similar exception a few months ago. Here is that thread:


I was able to work around it, but I never did find out what the cause of it was. Hope this additional data point helps,

-Sid

Christos L.

unread,
Jan 4, 2012, 2:57:12 PM1/4/12
to Morphia
Hi Sid, thanks for your reply !
Unfortunately I can't remove the @Reference annotation because the
object AddressCity really references AddressDepartment :(


On Jan 4, 8:13 pm, Siddhartha Kasivajhula <CountVajh...@gmail.com>
wrote:

Christos L.

unread,
Jan 4, 2012, 5:20:38 PM1/4/12
to Morphia
Youhou, I just found the solution !
I'm not really sure what happened, but here are the steps I followed :

First of all, I changed the snipet like this (I don't know if it
counts, but you never know) :

final Query<AddressCity> query = ds.find(AddressCity.class);
query.filter("department", new
Key<AddressDepartment>(AddressDepartment.class, new
ObjectId("4ef315c46f46c52f3373c904")));
query.order("name");
query.asList();

This didn't seem to work.
But, after that I made some tests and I had the same problem with
other classes in my project.
The thing is that I use spring mvc, and when the application is
started and I invoke the DAOs (@Repository) everything works fine !
But when I run from a separate class (Test.java), instanciating
mongodb and morphia manually, the code of the DAO's didn't seem to
work (I copy-past from the DAO's to Test.java) !

So I searched all my objects to see what's wrong.
I eventually found that I forgot to put a @Reference annotation to the
"Address" encapsulating class :

Address :
private AddressCity city;
@Reference private AddressDepartment department;
@Reference private AddressCountry country;

so I just added a @Reference annotation :
@Reference private AddressCity city;

And after that I retested Test.java and it worked !

Now, there are some things I don't get :
- The class Address.java wasn't involved during my tests...
theorically, it shouldn't be a problem
- I removed the @Reference annotation and it still works O_o

So I don't know what to think right now. The problem seems solved but
I'm not sure why.

Last thing :

I also have a custom DataStore implementation, that spring calls when
my app starts.
"public class DataStoreCustomImpl extends DatastoreImpl implements
Datastore..."

I always call this implementation in order to retrieve a DataStore.
In order to avoid a warning in the logs, inside this implementation I
overrided the "find(final Class<T> clazz)" method like this :

/*
* (non-Javadoc)
*
* @see com.google.code.morphia.DatastoreImpl#find(java.lang.Class)
*/
@Override
public <T> Query<T> find(final Class<T> clazz) {
// Returns the Query object with disabled validation in order to
avoir
// some warnings.
// See http://code.google.com/p/morphia/issues/detail?id=296
return super.find(clazz).disableValidation();
}


Maybe it also has something to do ? I sincerely don't know.
I overrided the method some time after I changed the snipet (see the
beggining of this post) in order to avoid the warnings.

Anyway, I put here all the steps I followed, maybe this will help
other people.
That's all folks, thanks and bb :)

Christos L.

unread,
Jan 4, 2012, 7:14:08 PM1/4/12
to Morphia
Guess I got excited too fast.

Finally, after debugging a lot I found that I had the same error in
other places too and the error was still here :(
Eventually, I understood what was wrong :
The "Address" object that I mentionned before, has the annotation
@Embedded. And yes, it is embedded in another object.
The thing is, that it has @Reference annotations inside, which seems
to cause the trouble.

I don't understand why can't I put @Reference attributes inside an
@Embedded object ?
Anyway, I moved the all the @Reference attributes from the @Embedded
class into an @Entity class and now it works fine.

Now I can go sleep peacefully :)
>  // Seehttp://code.google.com/p/morphia/issues/detail?id=296
Reply all
Reply to author
Forward
0 new messages