Java MongoDB Morphia:通过 ObjectId id 查找对象

Java MongoDB Morphia: find a object by ObjectId id

我正在使用 Morphia 和 DAO Class。我有一个 Class 和一个 Id ObjectId:

@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class GeoProfileVo extends ResponseVo implements Serializable{

    private static final long serialVersionUID = -4975628041316056892L;

    @Id private ObjectId id;

    private String email;
    private String name;
    private String city;

    //Getters, Setters and toString
}

GeoProfileDAO:

public class GeoProfileDAO extends BasicDAO<GeoProfileVo, ObjectId>{

    public GeoProfileDAO(Morphia morphia, MongoClient mongoClient, String db) {
        super(mongoClient, morphia, db);
    }

    public GeoProfileVo findByNme(String name){
        return getDs().find(GeoProfileVo.class, "name", name).get();
    }

    //Here is the problem
    public GeoProfileVo findById (ObjectId id){
        //return getDs().find(GeoProfileVo.class).field("id").equal(id).get();
        return getDs().get(GeoProfileVo.class, id);
    }

    public ObjectId saveGeoProfile(GeoProfileVo geoProfileVo){
        return (ObjectId) getDs().save(geoProfileVo).getId();
    }
}

我的服务:

public class GeolocationService implements Serializable{

    private static final long serialVersionUID = 2071937170723089158L;

    /** The Constant log. */
    private static final Logger LOGGER = Logger.getLogger(GeolocationService.class.getName());

    private MongoClient mongoClient;
    private GeoProfileDAO geoProfileDAO;

    public GeolocationService(){
        super();
        LOGGER.info("[GeolocationService - Constructor] - init");

        //mongoClient:
        mongoClient = new MongoClient("localhost",27017);

        //morphia:
        Morphia morphia = new Morphia();
        morphia.map(GeoProfileVo.class);

        //morphia dao:
        geoProfileDAO = new GeoProfileDAO(morphia, mongoClient, "mydb");
    }

    public GeoProfileVo updateGeoProfile(GeoProfileVo geoProfileVo) throws GeoProfileNotFoundException{
        LOGGER.info("[GeolocationService - updateGeoProfile] - init");
        long currentSystemTime=System.currentTimeMillis();

        if(geoProfileVo == null){
            LOGGER.error("[GeolocationService - updateGeoProfile] - geoProfileVo cannot be null");
            throw new IllegalArgumentException();
        }
        if(geoProfileVo.getId() == null){
            LOGGER.error("[GeolocationService - updateGeoProfile] - ID cannot be null");
            throw new IllegalArgumentException();
        }

        GeoProfileVo geoProfileVoEntity = geoProfileDAO.findById(geoProfileVo.getId());
        if(geoProfileVoEntity==null){
            LOGGER.error("[GeolocationService - updateGeoProfile] - geoProfileVo not found in BD");
            throw new GeoProfileNotFoundException();
        }

        LOGGER.debug("[GeolocationService - updateGeoProfile] - Finish Timing:"+(System.currentTimeMillis()-currentSystemTime));
        return geoProfileDAO.updateGeoProfile(geoProfileVo);
    }

    //CRUD

}

我可以通过电子邮件、姓名或城市进行搜索,在 BD 中插入一个对象,但我无法通过 ID 进行搜索。在 google 中,我只找到有关 String id 的信息,而没有找到有关 id 类型 ObjectId 的很多信息。当我尝试通过 ObjectId Id 查找时,没有找到任何内容并且 returns null.

例如,当我通过电子邮件查找时,returns:

{
       "id":    {
          "timestamp": 1432028968,
          "machineIdentifier": 9913253,
          "processIdentifier": 7516,
          "counter": 8215016
       },
       "email": "aaa@gmail.com",
       "name": "john",
       "city": "Madrid"
}

我调用了一个 WS,它使用具有相同 ID 的相同对象调用 createGeoProfile 服务,但在 Eclipse IDE 中,每个调用中的 "id" 是不同的。也许问题就在这里,但我不明白。

如何找到 ID 类型为 ObjectId 的对象?

当我在 BD 中插入对象时,他的解决方案是 return a ObjectId.toString()。我理解这个objectId类似于一个Hash,所以当我想通过Id查找时,我无法发送一个ObjectId类型,因为这个ObjectId发生了变化。为此,我们必须 return 一个 toString() (这部分是我没有理解的)。

使用这个字符串,我们实例化一个 ObjectId,我们用它来按 id 查找:

public GeoProfileVo findById (String id){
    ObjectId oid = new ObjectId(id);
    return getDs().find(GeoProfileVo.class).field("id").equal(oid).get();
}

public String saveGeoProfile(GeoProfileVo geoProfileVo){
    return getDs().save(geoProfileVo).getId().toString();
}

最后,为了避免出现我不会使用的 ObjectId 类型,我将 GeoProfileVo 中的 Id 更改为 String 类型。

@Id private String id;

现在,FindById的响应中,包含String类型的id:

{
   "id": "555c44e39743a5141c00d0a1",
   "email": "aaa@gmail.com",
   "name": "john",
   "city": "Madrid"
}