2017-08-20 20 views
1

Husband.java春データJPA @OneToOne注釈無限再帰エラー

package com.example.demo.com.example.domain; 

import lombok.Data; 
import lombok.EqualsAndHashCode; 
import lombok.NoArgsConstructor; 
import lombok.ToString; 

import javax.persistence.*; 


//@Data 
//@NoArgsConstructor 
//@EqualsAndHashCode 
//@ToString 
@Entity 
@Table(name = "t_husban") 
public class Husband { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 
    private String job; 

    @OneToOne 
    @JoinColumn(name = "wife_fk",referencedColumnName = "id") 
    private Wife wife; 

    //omitted getter/setter 
} 

Wife.java

package com.example.demo.com.example.domain; 

import lombok.Data; 
import lombok.EqualsAndHashCode; 
import lombok.NoArgsConstructor; 
import lombok.ToString; 

import javax.persistence.*; 

//@Data 
//@NoArgsConstructor 
@EqualsAndHashCode(exclude = "husband",callSuper = false) 
@Entity 
@Table(name = "t_wife") 
public class Wife { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 

    @OneToOne(mappedBy = "wife",cascade = {CascadeType.ALL}) 
    private Husband husband; 

    //omitted getter/setter 
} 

Service.java

@Service 

    public class TestOneToOneEitherSide { 

     @Autowired 
     private WifeRepository wifeDao; 

     @Autowired 
     private HusbandRepository husbandDao; 
     public Husband testCreate() { 

      Husband husband = husbandDao.findByName("Wang"); 
      return husband; 
     } 
    } 

春データjpaを使用してデータベースから夫を照会すると、結果にnfinite再帰が発生し、次の画像が表示されます。@OneToOneアノテーションを使用している間に何か問題がありますか?または、私は間違った方法で注釈を使用します。

the picture

+1

コントローラーで戻したいのですか? –

+0

** JSON **の無限再帰を意味しますが、JPAでは意味しません。おそらく、あなたのJSONの使用に問題があります。それで、JPAが生成したものと何を伝えているのか見てみましょう。そうすれば、それを引き起こすステップを見ることができます。 –

+0

** stackoverflowerror ** ** husband **をController.Soに返すときに発生します。 husbandDao.findByName( "Wang") – Holinc

答えて

1

これは既知の問題、あなたは双方向の関係を持っているとき、ジャクソンはその論理的には無限の再帰を持っているので、他の側から一方の各参照をシリアライズしようとしています。

ソリューション:それには多くのソリューションがありますが、あなたはまた、JsonManagedReference/@ JsonBackReference、チェック@使用することができます

@EqualsAndHashCode(exclude = "husband",callSuper = false) 
@Entity 
@Table(name = "t_wife") 
public class Wife { 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

private String name; 

@OneToOne(mappedBy = "wife",cascade = {CascadeType.ALL}) 
@JsonIgnore 
private Husband husband; 

//omitted getter/setter 
} 

無限再帰を壊すので、注釈付きの参照をシリアル化を避けるために片側に@JsonIgnoreを使用することができますこのlinkの詳細については、

この回答には1つの問題があります。妻の方向をシリアル化しようとすると、解決策がシリアル化されないため、夫のオブジェクトを持たないことになります。

このlinkに記載されている、いいアイデアがあります。アイデアは親エンティティへの参照を生成することです。したがって、夫をシリアル化する場合は、夫 - >妻 - > [夫旦那の代わりに] @JsonIdentityInfoでエンティティに注釈を付けるだけです。

@EqualsAndHashCode(exclude = "husband",callSuper = false) 
@Entity 
@Table(name = "t_wife") 
@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id") 
public class Wife { 

@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id") 
@Entity 
@Table(name = "t_husban") 
public class Husband { 
@Id 
+0

正常に動作し、HTMLページに書き出すことができます。しかし、** IDEA **でデバッグすると、私はリンクが見える無限の再帰があることがわかります[pic link](https://i.stack.imgur.com/HQumL.png)。それはスタックオーバーフローエラーを引き起こすでしょうか? – Holinc

+0

@Holincいいえ、これは無限の再帰ではありません。関係のすべての側がマッピングされているので、デバッガ上でこのように見えます。 –