6

Below is a follow-up question to Question 13832188:

I'm using spring-data-mongodb version 1.1.1.RELEASE. I am able to persist an object if all the member variables are primitive types, even if the names of the @PersistenceConstructor arguments don't match exactly the names of the member variables by using the @Field and @Value annotations.

However, I get a MappingInstantiationException when I try to persist objects that contain other objects. My questions:

  • Is this a bug in spring-data-mongodb or am I doing something wrong?
  • What needs to change so that I can properly persist objects containing objects?

.

org.springframework.data.mapping.model.MappingInstantiationException: Could not instantiate bean class [com.recorder.TestRecorder2$ObjectContainer]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
    at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:77)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:229)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:209)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:173)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:169)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:72)
    at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:1820)
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1542)
    at org.springframework.data.mongodb.core.MongoTemplate.findAll(MongoTemplate.java:1064)
    at com.recorder.TestRecorder2.testObjectContainer(RecorderTest2.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.recorder.TestRecorder2$ObjectContainer]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:158)
    at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:75)
    ... 34 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
    ... 35 more

My PrimitiveContainer and ObjectContainer classes are listed below:

@Document
class PrimitiveContainer {

    @Field("property") 
    private final int m_property;

    @PersistenceConstructor
    public PrimitiveContainer(@Value("#root.property") int a_property) {
        m_property = a_property;
    }

    public int property() {
        return m_property;
    }
}

@Document
class ObjectContainer {

    @Field("property") 
    private final PrimitiveContainer m_property;

    @PersistenceConstructor
    public ObjectContainer(@Value("#root.property") PrimitiveContainer a_property) {
        m_property = a_property;
    }

    public PrimitiveContainer property() {
        return m_property;
    }
}

**UPDATE: ** Curiously, changing the string in the @Field annotation to something other than "property" or removing the @Field annotation entirely for the ObjectContainer m_property allows spring-data-mongo-db to property re-instantiate my persisted ObjectContainer class. I don't understand why this works. Anyone have any ideas?

Community
  • 1
  • 1
Ben Baumgold
  • 307
  • 1
  • 4
  • 12

1 Answers1

2

You seem to have found a bug. The value resulting from the first Spel expression evaluation is a DBObject and not actually translated into the parameter type. I've already have some code here locally that fixes that. Would you mind creating a ticket against Spring Data MongoDB to file this as a bug?

Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211
  • I've created [DATAMONGO-592](https://jira.springsource.org/browse/DATAMONGO-592) to track this issue. Thanks for your help!! – Ben Baumgold Dec 14 '12 at 05:25
  • I also found that I can't property persist objects that contain primitive arrays. Is the bug that's preventing me from properly persisting objects that contain objects the same bug that's preventing me from properly persisting objects containing primitive arrays? See the details of the array issue in [StackOverflow 13884637](http://stackoverflow.com/questions/13884637) – Ben Baumgold Dec 14 '12 at 18:55