Hi,
Thanks for the input. I know Spring Data generally does support JavaMoney (JSR 354/Moneta) but not sure about individual modules. There is more than this example at least on a PoC level I also deal with PSD2 support backed by MongoDB where I believe the same type of persistence is used.
Are there concrete examples?
As for the XML config, I simply inherited the example it has not been maintained by the original author over 3 years ago: https://github.com/skizware/money-tracker
So it was created in the ancient past 😉
Cheers,
Werner
Hi all,
there's more to that than finding out which constructor to use as that already requires knowledge about the way you want to persist the object into MongoDB: as a scalar formatted string or as nested document with the amount and currency in separate fields?
If you cannot add mapping information to the domain type itself, the easiest way is defining both a Converter<MonetaryAmount, Document> and Converter<Document, MonetaryAmount> and register them via AbstractMongoConfiguration (there's an awful lot of XML configuration in your example. You're not stuck in the ancient past, are you, Werner? ;).
In general Spring Data supports classes with either a canonical (complex) constructor or one explicitly annotated with @PersistenceConstructor. Instance creation is then performed using ASM generated factory classes calling that constructor explicitly to avoid the reflection overhead.
Cheers,
Ollie
> Am 30.05.2018 um 15:15 schrieb Werner Keil <werner@xxxxxxxxxxx>:
>
> Hi,
>
> I came across a problem trying to persist MonetaryAmount instances like FastMoney with Spring Data MongoDB in a forked project:
> https://github.com/JavaMoney/money-tracker/tree/master/money-tracker-persistence
> (please be aware that project is GPL3)
>
> org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate org.javamoney.moneta.FastMoney using constructor NO_CONSTRUCTOR with arguments
> at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:64)
> at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:83)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:251)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:231)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1185)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$200(MappingMongoConverter.java:78)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1133)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1096)
> at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:78)
> at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:63)
> at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:71)
> at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:83)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:251)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:231)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readCollectionOrArray(MappingMongoConverter.java:906)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1183)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$200(MappingMongoConverter.java:78)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1133)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1096)
> at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:78)
> at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:63)
> at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:71)
> at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:83)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:251)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:231)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:191)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:187)
> at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:78)
> at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:2200)
> at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1882)
> at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1705)
> at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1688)
> at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:601)
> at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:566)
> at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:558)
> at com.skizware.money.tracker.persistence.repository.impl.UserRepositoryImpl.findUserMoneyTrackersByEmail(UserRepositoryImpl.java:83)
> at com.skizware.money.tracker.persistence.repository.impl.UserRepositoryImpl.findByEmail(UserRepositoryImpl.java:59)
> at com.skizware.money.tracker.service.impl.MoneyTrackerServiceImpl.getUserByEmail(MoneyTrackerServiceImpl.java:21)
> at com.skizware.money.tracker.service.impl.MoneyTrackerServiceImpl.enrollUser(MoneyTrackerServiceImpl.java:26)
> at com.skizware.money.tracker.service.MoneyTrackerServiceTest.testEnrollUser_UserEmailAlreadyExists(MoneyTrackerServiceTest.java:67)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
> at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
> at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
> at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
> at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
> at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
> at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
> at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
> at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
> at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
> at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
> at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
> Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.javamoney.moneta.FastMoney]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.javamoney.moneta.FastMoney.<init>()
> at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:107)
> at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:61)
> ... 68 more
> Caused by: java.lang.NoSuchMethodException: org.javamoney.moneta.FastMoney.<init>()
> at java.lang.Class.getConstructor0(Class.java:3082)
> at java.lang.Class.getDeclaredConstructor(Class.java:2178)
> at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104)
> ... 69 more
>
> Basically FastMoney or Money do not have a constructor. It seems SpringData relies on a constructor here.
>
> Does this work with JNoSQL? If so I could try to migrate the persistence module to it. Help is greatly appreciated if you have not problem with that code under the GPL. I'd propose a PR to the original project if it works, otherwise there are no problems, we just must refrain from using anything directly in JNoSQL examples ;-)
>
> Regards,
> Werner
>
>
> _______________________________________________
> jnosql-dev mailing list
> jnosql-dev@xxxxxxxxxxx
> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
> https://dev.eclipse.org/mailman/listinfo/jnosql-dev