杰克逊/没有序列化器发现上课

时间:2014-01-26 15:23:44

标签: scala serialization neo4j jackson spring-data-neo4j

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的人是否已经遇到过此问题?

2 个答案:

答案 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),升级对你的配置来说可能并不简单。