バージョン2.5.7以降Spring Data RESTは[ 〜#〜] put [〜#〜]リソースを更新するリクエスト関連するリソースがあります。PATCHリクエストとは異なり、期待どおりに動作します!
たとえば、Person
はAddres
と多対1の関連付けがあります。 SDR v.2.5.6(Spring Boot v.1.4.3)でPUTリクエストを実行すると、すべて正常に機能します。しかし、バージョン2.5.7(つまり、Spring Boot v.1.4.4)に切り替えると、エラーが発生します。
アドレスのインスタンスを構築できません:文字列値から逆シリアル化する文字列引数コンストラクタ/ファクトリメソッドがありません
同じことが他のタイプの関連付けでも発生します。たとえば、1対多(単方向および双方向)の場合です。myアプリケーション例コードとテスト。
この問題は、最新の安定した1.5.6バージョンと最新の2.0.0を含む1.4.4以降のSpring Bootのallバージョンに存在します。 -スナップショットバージョン!
この状況を回避するには、SDR v.2.5.6(Spring Boot v.1.4.3)に切り替えるだけです。
私はあなたが問題で遊ぶのを助けるためにPostmanリクエストのコレクションを用意しました: SDR PUT Issue
UPDATE 2017-08-14
エラーCan not construct instance of Address: no String-argument constructor/factory method to deserialize from String value
を回避する方法を見つけました。
このプロジェクトでは Lombok を使用しているので、 生成されたコンストラクター で@ConstructorProperties
アノテーションの使用を抑制するようにLombokに指示するだけで済みます。そこで、「lombok.config」ファイルにlombok.anyConstructor.suppressConstructorProperties=true
を設定すると、エラーはなくなりました。
残念ながら、新しい問題が見つかりました-PUTリクエストは関連するオブジェクトをまったく更新しません!
以下の例はこれを示しています。住所をaddresses/1
(初期値)からaddresses/2
に変更してPersonを更新しようとすると、同じままになります:addresses/1
!前の問題と同様に、これは1.4.4以降のSpring Bootのallバージョンに存在します(SDR-v.2.5.7以降)。
プロジェクトをデバッグしたところ、問題の理由がメソッドDomainObjectReader#mergeForPut
に隠されていることがわかりました( そのソース を参照)-itnever関連するリソースを新しいリソースに置き換えます。
この問題を Spring JIRA に投稿する前に、プロジェクトでこの問題が発生した場合はここに報告してください -)。
私のテストを取得することができます ここ そしてあなたのプロジェクトでそれをチェックしてください-テストは「スタンドアロン」であり、他のクラス/モジュールに依存しません(H2のみを除く、私は願っています)。
@Entity
public class Person {
private String name;
@ManyToOne
private Address address;
// other stuff
}
@Entity
public class Address {
private String street;
// other stuff
}
Personを更新しようとしています:
PUT http://localhost:8080/api/persons/1
{
"name": "person1u",
"address": "http://localhost:8080/api/addresses/2"
}
正しい応答を得る:
{
"name": "person1u",
"_links": {
"self": {
"href": "http://localhost:8080/api/persons/1"
},
"person": {
"href": "http://localhost:8080/api/persons/1"
},
"address": {
"href": "http://localhost:8080/api/persons/1/address"
}
}
}
次に、「新しい」個人の住所を確認します-住所は更新されませんでした:
GET http://localhost:8080/api/persons/1/address
{
"street": "address1",
"_links": {
"self": {
"href": "http://localhost:8080/api/addresses/1"
},
"address": {
"href": "http://localhost:8080/api/addresses/1"
}
}
}
UPDATE 2017-08-24
Scott Cのおかげで answer 、SDRにはbugがあり、2つのチケットで説明されていることがわかりました:- DATAREST-1001 および DATAREST-1012 。
問題が発生したようです すでにバグとして報告されています :-確認してください。私が知る限り、これはあなたが上で報告している問題です。
以前の回答をこのバグレポートに修正していることに注意してください。
これはSpringData RESTのバグであり、報告する必要があることに同意します。
私のプロジェクトでも同じ問題があり、PATCHリクエストを介したエンティティの更新は正常に機能しますが、PUTリクエストは特定のエンティティのフィールドのみを更新し、関連するリソースは更新しません。
なぜこれをバグと見なすのですか?
記録のために、私はSpring Data REST 2.6.3を使用しています。