Neo4j服务器提供了一个处理Json格式的REST API。 我使用spring-data-neo4j轻松地将域对象(在Scala中)映射到neo4j节点。 以下是我的用户节点示例:
@NodeEntity
class User(@Indexed @JsonProperty var id: UserId)
UserId
是一个价值对象:
final case class UserId(value: String) {
override def toString = value
}
object UserId {
def validation(userId: String): ValidationNel[IllegalUserFailure, UserId] =
Option(userId).map(_.trim).filter(!_.isEmpty).map(userId => new UserId(userId)).toSuccess(NonEmptyList[IllegalUserFailure](EmptyId))
}
在运行时,我收到了这个错误:
Execution exception[[RuntimeException: org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.myApp.domain.model.user.UserId and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.HashMap["value"])]]
然后,我在网上看到了这个小article,解释了解决方案。
我最终得到了这个User
课程:
@NodeEntity
@JsonAutoDetect(Array(JsonMethod.NONE))
class User (@Indexed @JsonProperty var id: UserId)
我还尝试将@JsonProperty
放在UserId
值对象本身上,如下所示:
JsonAutoDetect(Array(JsonMethod.NONE))
final case class UserId(@JsonProperty value: String) {
override def toString = value
}
但我仍然得到完全相同的错误。
使用Scala的人是否已经遇到过此问题?
答案 0 :(得分:4)
我认为你的问题是案例类不会生成杰克逊期望的JavaBean样板(或者适当注释的成员字段)。例如,我相信Scala在UserId
:
public java.lang.String value();
杰克逊不知道该怎么做。它不是可识别的字段或JavaBean样式的方法(即getValue()
或setValue()
)。
我还没有使用它,但你可能想尝试jackson-module-scala作为一个围绕杰克逊的更多Scala感知包装器。另一个选项是spray-json。
答案 1 :(得分:1)
错误的原因是您似乎正在使用的Jackson版本(1.x)未将“value”属性与构造函数参数匹配。当应用于构造函数时,@JsonProperty
通常需要一个name参数来匹配属性的参数;对于您当前的设置,我相信以下内容可行:
case class UserId @JsonCreator() (@JsonProperty("value") value: String)
Jackson Scala模块还为Scala-isms提供了更多支持,并且可能在没有任何Jackson特定注释的情况下处理UserId
类。也就是说,你的杰克逊版本已经很老了(目前的最新版本是2.3.1),升级对你的配置来说可能并不简单。