Java中的MongoJack获取调用方法getSavedObjects的异常

时间:2014-02-21 07:04:45

标签: java mongodb jackson

我遇到使用MongoJack将Java POJO映射到MongoDb记录的问题。似乎我可以使用映射将对象插入到DB中,但是当我使用getSavedObjects方法时,抛出以下异常:

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at org.mongojack.internal.util.JacksonAccessor.invoke(JacksonAccessor.java:153)
at org.mongojack.internal.util.JacksonAccessor.findDeserializer(JacksonAccessor.java:44)
at org.mongojack.internal.util.IdHandlerFactory.getIdHandlerForProperty(IdHandlerFactory.java:40)
at org.mongojack.JacksonDBCollection.<init>(JacksonDBCollection.java:137)
at org.mongojack.JacksonDBCollection.wrap(JacksonDBCollection.java:181)
at com.mytest.testdb.tests.integration.persistence.PersistenceIntegrationTests.test_shouldInsertTestObject(PersistenceIntegrationTests.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.mongojack.internal.util.JacksonAccessor.invoke(JacksonAccessor.java:149)
... 10 more
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Argument #0 of constructor [constructor for com.mytest.testdb.tests.integration.persistence.PersistenceIntegrationTests$TestObject, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator()}] has no property name annotation; must have name when multiple-paramater constructor annotated as Creator
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:272)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:247)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:146)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:322)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:2990)
... 13 more
Caused by: java.lang.IllegalArgumentException: Argument #0 of constructor [constructor for com.mytest.testdb.tests.integration.persistence.PersistenceIntegrationTests$TestObject, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator()}] has no property name annotation; must have name when multiple-paramater constructor annotated as Creator
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:283)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:263)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:168)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:405)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:354)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:267)
... 17 more

这是我创建的课程......

public class TestObject{
    private String id;
    private String myString;

    public TestObject(String myString) {
        this.myString = myString;
    }

    @JsonCreator
    public TestObject(@JsonProperty("_id")String id, @JsonProperty("my_string") String myString) {
        this.id = id;
        this.myString = myString;
    }

    @ObjectId
    @JsonProperty("_id")
    String getId() {
        return id;
    }

    @ObjectId
    @JsonProperty("_id")
    void setId(String id){
        this.id = id;
    }

    @JsonProperty("my_string")
    String getMyString() {
        return myString;
    }

    @JsonProperty("my_string")
    void setMyString(String myString) {
        this.myString = myString;
    }
}

...这是我用来保存它并读取结果的代码

@Test
public void PersistenceIntegrationTests.test_shouldInsertTestObject(){
    MongoClient mongoClient = new MongoClient("localhost", 27017);
    DB db = mongoClient.getDB("TestDb");
    TestObject testObject = new TestObject(1,"My String 1");
    DBCollection dbCollection = db.getCollection("TestObjects");
    JacksonDBCollection<TestObject, String> collection = 
        JacksonDBCollection.wrap(dbCollection, TestObject.class, String.class);

    WriteResult<TestObject,String> result = collection.insert(testObject);

    List<TestObject> savedObjects = result.getSavedObjects();
}

我确定它与JsonCreator注释有关,但我似乎无法弄清楚如何,我一直在关注MongoJack网站上的tutorial,但当你复制该代码时,它并没有甚至编译。当插入数据库并调用getSavedObjects时,如何让对象正确地序列化结果?

注意:我可以验证记录是否已成功写入数据库。

1 个答案:

答案 0 :(得分:0)

事实证明,如果你的pojo类是一个内部类,虽然你可以将记录写入数据库,但是你很难用mongojack将它从mongo序列化回到pojo中。一旦我从与Test相同的文件中提取出TestObject,一切正常。

注意:当我正在开发我正在开发的应用程序中的新概念或框架时,我会从单元测试中测试它们,并且我经常将我的类编写为内部类。测试只是为了让我在玩的时候就在我身边。如果我想使用这个实验代码中的任何一个,那么如果它们最终有用,则提取类,或者如果它与我正在做的事情没有进一步关联,则删除测试。