繁体   English   中英

在Spring Boot应用程序上的JPA(加上Jackson)中坚持“计算”字段

[英]Persist “computed” field in JPA (plus Jackson) on Spring Boot application

我有一个JPA实体,看起来像:

public final class Item implements Serializable {
  @Column(name = "col1")
  private String col1;

  @Column(name = "col2")
  @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
  private String col2;

  @Column(name = "col3")
  private String col3;

  Item() { }

  public Item(String col1, String col2) {
    this.col1 = col1;
    this.col2 = col2;
    col3 = col1 + col2 + "some other stuff";
  }

  // getters, equals, hashCode and toString
}

我希望能够坚持col3 我正在通过POST发送请求,如下所示:

{
  "col1": "abc",
  "col2": "def"
}

...而我收到的是这样的:

[
    {
        "createdAt": "2017-09-07T19:18:17.04-04:00",
        "updatedAt": "2017-09-07T19:18:17.04-04:00",
        "id": "015e5ea3-0ad0-4703-af04-c0a3d46aa836",
        "col1": "abc",
        "col3": null
    }
]

最终, col3不会col3在数据库中。 我没有二传手。

有什么办法可以做到这一点?

更新

公认的解决方案是“较少干扰”的解决方案。 Jarrod Roberson提出的建议也可以完美地工作。 最终,您可以通过在col2上使用setter并在那里设置col3的值来实现相同的目的,但是我不喜欢这个……尽管个人喜好。

之所以不能持续下去,是因为从未真正调用过您提供的带有col1col2属性的构造函数。 当spring从您发送到服务器的JSON中映射(借助jackson)时,它使用默认构造函数创建对象,然后调用setter(有时通过反射)来设置值。 因此, col3的数据库中存储的值始终为空。 请参阅Jarrod Roberson的答案如何解决它:)。

您正在寻找的是@JsonCreator它的用法如下:

@JsonCreator()
public Item(@JsonProperty("col1") String col1, @JsonProperty("col2") String col2) {
  this.col1 = col1;
  this.col2 = col2;
  this.col3 = col1 + col2 + "some other stuff";
}

然后删除默认的no-args构造函数,Jackson将使用此构造函数,您想要的将自动进行

这是1.x时代的一项非常古老的功能 您还可以注释static 工厂方法 ,并使构造函数private以用于需要使用更复杂的逻辑(例如使用“ 构建器模式”构造的事物)的情况。

这是一个例子:

@JsonCreator()
public static Item construct(@JsonProperty("col1") String col1, @JsonProperty("col2") String col2) {
  return new Item(col1, col2, col1 + col2 + "some other stuff");
}

private Item(final String col1, final String col2, final String col3) {
  this.col1 = col1;
  this.col2 = col2;
  this.col3 = col3;
}

尽管有一个可以接受的答案,但它似乎过于复杂,需要删除违背JPA规范的默认构造函数。

第2.1节

实体类必须具有no-arg构造函数。 实体类也可以具有其他构造函数。 无参数构造函数必须是公共的或受保护的。

无需让Jackson参与其中。 您可以简单地使用JPA预持久侦听器来确保在刷新操作之前已设置col3

https://docs.jboss.org/hibernate/orm/4.0/hem/zh-CN/html/listeners.html

public final class Item implements Serializable {
  @Column(name = "col1")
  private String col1;

  @Column(name = "col2")
  @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
  private String col2;

  @Column(name = "col3")
  private String col3;

  Item() { }

  @PrePersist
  public void updateCol3(){
      col3 = col1 + col2;
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM