REST アプリケーションには Jersey/Jackson を使用します。着信 JSON 文字列は、Jackson によってバックエンドの @Entity オブジェクトにマッピングされ、永続化されます。
問題は、すべてのエンティティに使用する基本クラスから発生します。これには protected id プロパティがあり、これを REST 経由でも交換して、依存関係を持つオブジェクトを送信すると、hibernate がこれらの依存関係を ID によって自動的にフェッチするようにします。
ただし、サブクラスでオーバーライドして public にしても、Jackson はセッターにアクセスしません。@JsonSetter も使用してみましたが、役に立ちませんでした。おそらくジャクソンは基本クラスを見て、IDにアクセスできないことを確認したため、設定をスキップしました...
@MappedSuperclass
public abstract class AbstractPersistable<PK extends Serializable> implements Persistable<PK> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private PK id;
public PK getId() {
return id;
}
protected void setId(final PK id) {
this.id = id;
}
サブクラス:
public class A extends AbstractPersistable<Long> {
private String name;
}
public class B extends AbstractPersistable<Long> {
private A a;
private int value;
// getter, setter
// make base class setter accessible
@Override
@JsonSetter("id")
public void setId(Long id) {
super.setId(id);
}
}
ここで、データベースにいくつかの As があり、REST リソースを介して新しい B を作成したい場合:
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Response create(B b) {
if (b.getA().getId() == null)
cry();
}
このような JSON 文字列を使用します{"a":{"id":"1","name":"foo"},"value":"123"}
。
着信 B には A 参照がありますが、ID はありません。
ベースクラスセッターを無視するか、代わりにサブクラスセッターを使用するようにジャクソンに指示する方法はありますか?
知ったばかり@JsonTypeInfo
ですが、これが必要なものなのか、それをどのように使用するのかわかりません。
助けてくれてありがとう!
編集
StaxMan は、ここに何かが欠けているのではないかと心配しているので、XML 注釈をセッター(私の答えで説明されているように):
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>path.to.rest.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>