Search code examples
javamorphia

How can I convert a Composite ID stored in a MongoDB into a Morphia Java entity object?


I have a problem when _id is a composite id. Then, I cannot convert it into a Morphia Java entity object.

The JSON in my MongoDB looks as follows:

{
    "_id" : {
        "id1" : "SAMPLE_ID1",
        "id2" : "SAMPLE_ID2"
    }
}

Java code:

import org.mongodb.morphia.annotations.Id;

@Entity(value = "MyCollection", noClassnameStored = true)
public class MyObject {

    @Id
    private MyObjectId thisId;

    //....
}

public class MyObjectId{

    @Property("id1")
    private String id1; 

    @Property("id2")
    private String id2;

    //.....
}

I am using morphia v1.3.2.

When I insert the object, I get the following exception:

java.lang.RuntimeException: java.lang.ClassCastException: org.bson.types.ObjectId cannot be cast to com.mongodb.DBObject at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:76) at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:850) at org.mongodb.morphia.mapping.Mapper.updateKeyAndVersionInfo(Mapper.java:725) at org.mongodb.morphia.DatastoreImpl.postSaveOperations(DatastoreImpl.java:1422) at org.mongodb.morphia.DatastoreImpl.postSaveOperations(DatastoreImpl.java:1408) at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:1292) at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:775) at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:758) .......

When I select the object, I get the following exception:

java.lang.RuntimeException: java.lang.ClassCastException: org.bson.types.ObjectId cannot be cast to com.mongodb.DBObject at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:76) at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:850) at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:282) at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:193) at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:134) at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:146) at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:117) at org.mongodb.morphia.query.QueryImpl.asList(QueryImpl.java:147) ......


Solution

  • I have a very similar setup that I got working. I think all you'll need to do is add @Entity to MyObjectId, so

    @Entity(noClassnameStored = true)
    public class MyObjectId { 
    
      @Property("id1")
      private String id1; 
    
      @Property("id2")
      private String id2;
    
      public MyObjectId() {
      }
    
      public MyObjectId(String id1, String id2) {
        this.id1 = id1;
        this.id2 = id2;
      }
    
    }
    

    I seem to recall that the no-args constructor was required for marshalling.