2016-09-21 15 views
0

以下のエンティティクラスモデルを使用してアプリケーションにHibernateを実行させようとしています。私はアプリケーションをロードすると無限ループに陥ることに気付きました。 CartとCartItemは双方向の関係にあり、エラーをスローします:java.lang.StackOverflowError。私はHibernateコミュニティでこの問題をGoogleに報告しましたが、これを修正する方法がわかりません。お手伝いください。オブジェクトのロード時にHibernateエラーが発生しました:java.lang.StackOverflowError

Hibernate community からの回答は、「私もこの無限ループの問題に遭遇しましエンドで働いていたソリューションでした:。 * @IdClass *でのみ@Id注釈を付ける 『メイン』クラス *あなたのですか@ PkのクラスのManyToOne、そして作るfetchType = LAZY * @OneToMany」

詳細のエラーを参照してくださいにfetchType = LAZYを行います

java.lang.StackOverflowError 
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:364) 
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111) 
    at org.hibernate.collection.PersistentBag.toString(PersistentBag.java:506) 
    at java.lang.String.valueOf(String.java:2854) 
    at java.lang.StringBuilder.append(StringBuilder.java:128) 
    at com.bfd.model.Cart.toString(Cart.java:66) 
    at java.lang.String.valueOf(String.java:2854) 
    at java.lang.StringBuilder.append(StringBuilder.java:128) 
    at com.bfd.model.CartItem.toString(CartItem.java:20) 
    at java.lang.String.valueOf(String.java:2854) 
    at java.lang.StringBuilder.append(StringBuilder.java:128) 
    at java.util.AbstractCollection.toString(AbstractCollection.java:458) 
    at org.hibernate.collection.PersistentBag.toString(PersistentBag.java:507) 
    at java.lang.String.valueOf(String.java:2854) 
    at java.lang.StringBuilder.append(StringBuilder.java:128) 
    at com.bfd.model.Cart.toString(Cart.java:66) 
    at java.lang.String.valueOf(String.java:2854) 
    at java.lang.StringBuilder.append(StringBuilder.java:128) 
    at com.bfd.model.CartItem.toString(CartItem.java:20) 
    at java.lang.String.valueOf(String.java:2854) 
    at java.lang.StringBuilder.append(StringBuilder.java:128) 
    at java.util.AbstractCollection.toString(AbstractCollection.java:458) 
    at 

Userクラス:

@Entity 
@Table(name = "user") 
public class User implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Column(name = "user_id") 
    private int userId; 
    // custom id generator class 
    @Id 
    @GenericGenerator(name = "login_id", strategy = "com.bfd.tools.UserIdGenerator") 
    @GeneratedValue(generator = "login_id") 
    @Column(name = "login_id") 
    private String loginId; 
    @NotBlank 
    @Size(max = 20, min = 5) 
    @Pattern(regexp = "[a-zA-Z]*") 
    @Column(name = "first_name") 
    private String firstName; 
    @NotBlank 
    @Pattern(regexp = "[a-zA-z]+([ '-][a-zA-Z]+)*") 
    @Size(max = 20, min = 5) 
    @Column(name = "last_name") 
    private String lastName; 
    @Size(min = 5) 
    @Pattern(regexp = "^\\S+$") 
    @Column(name = "password") 
    private String password; 
    @Size(max = 40, min = 10) 
    @Column(name = "address") 
    private String address; 
    @Column(name = "registered_date") 
    private Date registerDate = new Date(
      Calendar.getInstance().getTime().getTime()); 
    @Column(name = "acc_balance") 
    private double accountBalance = 1000; 
    @Column(name = "email") 
    @NotBlank 
    @Email 
    private String email; 
    @Column(name = "enabled") 
    private boolean enabled = false; 
    @OneToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "cart_id") 
    private Cart userCart; 
...getter and setter 

カートクラス:

@Entity 
@Table(name = "cart") 
     public class Cart implements Serializable { 
      private static final long serialVersionUID = 1L; 
     @Id 
     @GeneratedValue 
     @Column(name = "cart_id") 
     private int cartId; 

     @Column(name = "session_id") 
     private String sessionId; 

     @Column(name = "purchased") 
     private Boolean purchased = false; 

     @OneToMany(mappedBy="parentCart",fetch=FetchType.EAGER,cascade=CascadeType.ALL) 
     private List<CartItem> cartItems; 
... getter and setter 

CartItemクラス:

@Entity 
@Table(name = "cartItem") 
    public class CartItem implements Serializable { 
     /** 
     * 
     */ 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue 
    @Column(name = "cartItem_id") 
    private int cartItemId; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name ="cart_id") 
    private Cart parentCart; 


    @OneToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "p_id") 
    private Product product; 

    @Column(name = "purchased_quantity") 
    private int purchasedQuantity; 

    @Column(name = "purchased_price") 
    private double purchasedPrice; 
    ... getter and setter 
+0

エンティティの1つのtoString()メソッド内で問題が発生しているようです。 toString()を上書きしましたか?はいの場合は、方法を投稿してください。 –

+0

あなたのクラスは "Serializable"を実装しています。つまり、クラスは文字列で表すことができます。このようにして、javaは "cart-> cart items-> cart parent-> cart items - > ..."の文字列を作成しようとするループに入ります。 "Serializable"を実装せずにテストしてみてください。それがうまくいくならば、そのループを解決しようとするのを止めるようにjavaに指示する方法を検索する必要があります。またはSerializableを実装しないでください。 –

+0

ニュースはありますか?あなたの問題を解決しますか? –

答えて

1

私はこの問題は、休止状態とは何の関係もありませんだと思います。

の方法をCartCartItemクラスで見ることなく、これらのクラスの両方でtoString()メソッドをチェックするとよいでしょう。

Cart toString()メソッドではCartItemオブジェクト、CartItem toString()メソッドではCart objectオブジェクトを印刷していると思います。

1

通常、問題は内部の循環関係です。最初のチェックequals。これはhibernateによって使用され、異なるクラスのequalsメソッドが互いに呼び出すことができます。無限の呼び出しがあり、最終的にはSO例外が生成されます。秒はtoStringとすることができます。コード内で使用すると、メカニズムは同じになります。オブジェクトの複雑な自己参照グラフで使用されても常に終了するかどうかを確認してください。

+0

アドバイスをいただきありがとうございます。私はこの問題を修正しますが、別のエラーが出ます:2016-09-22 21:54:55 ERROR CustomLogger:106 - オブジェクト作成エラー。メッセージ:[同一の識別子値を持つ別のオブジェクトが既にセッションに関連付けられていました:[com.bfd.model.Product#p_00014];ネストされた例外はorg.hibernate.NonUniqueObjectExceptionです:同じ識別子値を持つ別のオブジェクトがすでにセッションに関連付けられていました:[com.bfd.model.Product#p_00014]] –

+0

これはまったく別の問題です。おそらくあなたはid自動生成を設定する必要があります – piotrek

0

オーバーライドされたメソッドequalsおよびhashcodeを削除してください。

関連する問題