I'm starting to use ArangoDB as the persistence layer for an existing java SpringBoot (and SpringData) application. There are many DTOs, all of which are immutable classes (using AutoValue).
There is, therefore, no default constructor, and arango is unable to instanatiate the dto in order to populate it from the DB.
Is it possible to have the arango spring data layer use the Builder as the way to instantiate and populate the class (ie during deserialization)
It is possible to have jackson use the dto's builder when unnarshalling from json, so as a fallback option, is it possible to configure arango/java/springdata to use jackson/json instead of velocypack ??
with thanks, Simon
update1
Thanks for the quick answer. One of the complications I am facing is with autovalue, the generated constructor will be private if there is a builder. I can take out the generated builder, and will get a package protected constructor, however I am also seeing this ...
com.arangodb.ArangoDBException: com.arangodb.velocypack.exception.VPackParserException: java.lang.InstantiationException: com.arangodb.springframework.core.convert.DBEntity
at com.arangodb.internal.util.ArangoDeserializerImpl.deserialize(ArangoDeserializerImpl.java:59) ~[arangodb-java-driver-4.4.0.jar:na]
at com.arangodb.internal.util.ArangoUtilImpl.deserialize(ArangoUtilImpl.java:92) ~[arangodb-java-driver-4.4.0.jar:na]
at com.arangodb.internal.ArangoExecutor.deserialize(ArangoExecutor.java:120) ~[arangodb-java-driver-4.4.0.jar:na]
.....
Caused by: com.arangodb.velocypack.exception.VPackParserException: java.lang.InstantiationException: com.arangodb.springframework.core.convert.DBEntity
at com.arangodb.velocypack.VPack.deserialize(VPack.java:398) ~[velocypack-1.1.0.jar:na]
at com.arangodb.internal.util.ArangoDeserializerImpl.deserialize(ArangoDeserializerImpl.java:55) ~[arangodb-java-driver-4.4.0.jar:na]
... 128 common frames omitted
Caused by: java.lang.InstantiationException: com.arangodb.springframework.core.convert.DBEntity
at java.lang.Class.newInstance(Class.java:427) ~[na:1.8.0_171]
at com.arangodb.velocypack.VPack.createInstance(VPack.java:488) ~[velocypack-1.1.0.jar:na]
at com.arangodb.velocypack.VPack.deserializeObject(VPack.java:450) ~[velocypack-1.1.0.jar:na]
at com.arangodb.velocypack.VPack.getValue(VPack.java:569) ~[velocypack-1.1.0.jar:na]
at com.arangodb.velocypack.VPack.deserialize(VPack.java:396) ~[velocypack-1.1.0.jar:na]
... 129 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.arangodb.springframework.core.convert.DBEntity.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_171]
at java.lang.Class.newInstance(Class.java:412) ~[na:1.8.0_171]
... 133 common frames omitted
update2
So... turns out there are 2 different issues, and neither of are actually problems with the arango sping data implementation (which seems good to me, better than what I've seen for similar mixed model document/graph DBs) First, reworking the auto value class to not use a generated builder, means the generated class is package proteced, and that works well, thanks to @Christian for that.
The second is - which I will take to a different question - concerns using the spring (crudrepo) 'save' to save a new document, but also provide a user generated id. This is a different issue from unmarshalling to an immutable object, so I will start a new question for that.
You can generate a constructor (can even be package protected) that takes all parameters (with your IDE or Lombok) of your DTO. If this isn't the only constructor inside your DTO, annotate the constructor with @PersistenceConstructor
.
UPDATE: Are your DTO classes abstract and are you passing them to Spring Data ArangoDB? If yes, this may be the cause of the exceptions you get. You should pass the generated concrete class.