ArangoDB 和 velocypack,使用不可变 类 作为 dto
ArangoDB and velocypack, using immutable classes as dtos
我开始使用 ArangoDB 作为现有 java SpringBoot(和 SpringData)应用程序的持久层。
DTO有很多,都是不可变的classes(使用AutoValue)。
因此,没有默认构造函数,arango 无法实例化 dto 以便从数据库中填充它。
是否可以让 arango spring 数据层使用 Builder 作为实例化和填充 class 的方式(即在反序列化期间)
从 json 解包时可以让 jackson 使用 dto 的构建器,因此作为后备选项,是否可以配置 arango/java/springdata 以使用 jackson/json 而不是 velocypack ??
非常感谢,
西蒙
更新1
感谢您的快速回答。我面临的复杂情况之一是自动值,如果有构建器,生成的构造函数将是私有的。我可以取出生成的生成器,并将获得一个受包保护的构造函数,但是我也看到了这个 ...
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
更新2
所以...原来有 2 个不同的问题,实际上都不是 arango sping 数据实现的问题(这对我来说似乎很好,比我在类似混合模型中看到的要好 document/graph数据库)
首先,将自动值 class 修改为 而不是 使用生成的构建器,这意味着生成的 class 受到包保护,效果很好,感谢@Christian那。
第二个是 - 我将把它带到另一个问题 - 关注使用 spring (crudrepo) 'save' 来保存新文档,但也提供用户生成的 ID。这与解组到不可变对象不同,因此我将为此提出一个新问题。
您可以生成一个构造函数(甚至可以是包保护的),它接受您的 DTO 的所有参数(使用您的 IDE 或 Lombok)。如果这不是 DTO 中唯一的构造函数,请使用 @PersistenceConstructor
.
注释构造函数
更新:
您的 DTO class 是抽象的吗?您是否将它们传递给 Spring Data ArangoDB?如果是,这可能是您获得异常的原因。您应该传递生成的具体 class.
我开始使用 ArangoDB 作为现有 java SpringBoot(和 SpringData)应用程序的持久层。 DTO有很多,都是不可变的classes(使用AutoValue)。
因此,没有默认构造函数,arango 无法实例化 dto 以便从数据库中填充它。
是否可以让 arango spring 数据层使用 Builder 作为实例化和填充 class 的方式(即在反序列化期间)
从 json 解包时可以让 jackson 使用 dto 的构建器,因此作为后备选项,是否可以配置 arango/java/springdata 以使用 jackson/json 而不是 velocypack ??
非常感谢, 西蒙
更新1
感谢您的快速回答。我面临的复杂情况之一是自动值,如果有构建器,生成的构造函数将是私有的。我可以取出生成的生成器,并将获得一个受包保护的构造函数,但是我也看到了这个 ...
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
更新2
所以...原来有 2 个不同的问题,实际上都不是 arango sping 数据实现的问题(这对我来说似乎很好,比我在类似混合模型中看到的要好 document/graph数据库) 首先,将自动值 class 修改为 而不是 使用生成的构建器,这意味着生成的 class 受到包保护,效果很好,感谢@Christian那。
第二个是 - 我将把它带到另一个问题 - 关注使用 spring (crudrepo) 'save' 来保存新文档,但也提供用户生成的 ID。这与解组到不可变对象不同,因此我将为此提出一个新问题。
您可以生成一个构造函数(甚至可以是包保护的),它接受您的 DTO 的所有参数(使用您的 IDE 或 Lombok)。如果这不是 DTO 中唯一的构造函数,请使用 @PersistenceConstructor
.
更新: 您的 DTO class 是抽象的吗?您是否将它们传递给 Spring Data ArangoDB?如果是,这可能是您获得异常的原因。您应该传递生成的具体 class.