2017-11-28 8 views
0

私はSpring JPAでORMマッピングについて質問します。@ManyToOneの関係でJSONのシリアライズを簡略化

は、単純なPersonクラスを考えてみましょう:

@Entity 
public class Person { 

    @Id 
    @NotNull 
    @Column(unique = true, updatable = false, name = "PERSON_ID") 
    private long personId; 

    @NotNull 
    @Size(min = 1) 
    private String name; 

    @OneToMany(mappedBy = "person", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private List<Car> cars; 

    public Person() { 
    } 
    //continue.... 

と単純なクラスの車:

@Entity 
public class Car { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "CAR_ID") 
    private long carId; 

    @NotNull 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "PERSON_ID") 
    private Person person; 

    @NotNull 
    @Size(min = 1) 
    private String typeOfCar; 

    public Car() { 
    } 
    //continue.... 

人は車でOneToManyの関係を持っています。

{ 
    "person": { 
    "personId": 200, 
    "name": "Jack" 
    }, 
    "typeOfCar": "Ferrari" 
} 

私が希望:carId私は現時点では新しい車を投稿するとき、私は(車のNULL可能リストから離れて)フルPersonオブジェクトを指定することを強制しています、自動生成されていることを想起し

{ 
    "person": 200, 
    "typeOfCar": "Ferrari" 
} 

このように、personId(Personエンティティのキ​​ー)のみを指定することで、車のオブジェクトをPOSTできるようになりました。

私はカーでPerson参照がキーとしてのみシリアル化され、オブジェクト全体ではなく、シリアル化される必要があると思います。

これを行うには?

次のようにこれまでのところ、私が試してみましたが車の中で人の参照に次の注釈@JsonIdentityReference@JsonIdentityInfoです:

@NotNull 
@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "PERSON_ID") 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "personId") 
@JsonIdentityReference(alwaysAsId = true) 
private Person person; 

を私は、私は取得しています単純化されたJSONをPOST 404以下:

"exception": "org.springframework.http.converter.HttpMessageNotReadableException", 
"message": "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: \n at [Source: [email protected]; line: 5, column: 1]Object id [2] (for myapp.ws.people.entity.Person) at [Source: [email protected]; line: 2, column: 13].", 
+1

あなたは基準クエリまたはJPQLを使用することはできますか? – pirho

+0

結合列で@notを削除する –

+0

いいえJPQLを使用できません。残念ながら、@ NotNullを削除しても何も変更されませんでした。 – Johan

答えて

1

私はそれを達成するための一つの方法は、

にあると思います210
  1. は2つのリポジトリを持っているあなたのサービスで、その後

    class CarDto { 
    private long person; 
    private String typeOfCar; 
    } 
    
  2. DTOクラスを作成します。人と車のためのもの。

    class PersonService { 
    
        public void post(CarDto car) { 
        Person person = personRepository.findByPersonId(car.getPerson()); 
        Car newCar = new Car(); 
        newCar.setPerson(person); 
        newCar.setTypeOfCar(car.getTypeOfCar); 
        carRepository.save(newCar); 
        } 
    
    } 
    
+0

私のコードでこれと何をすべきか) – Johan

+1

私はあなたがしたいポストコールを達成する方法を尋ねたと思う。これは1つのアプローチです。 UはDTOクラスを作成し、それをコントローラーの要求本体として使用し、答えに記載されているようなサービスメソッドを呼び出す必要があります。 DTOクラスを作成することは、あなたがしたいことを達成するための非常に一般的な方法です。 – TrafLaw

+0

はい、これが答えです – Johan