加载对象时出现Hibernate错误:java.lang.StackOverflowError

时间:2016-09-21 12:50:51

标签: java hibernate hibernate-mapping

我正在尝试让我的应用程序使用以下实体类模型运行hibernate。我注意到当我加载我的应用程序时,我遇到了无限循环。我的意思是因为我的Cart和CartItem有双向关系,它会抛出一个错误:java.lang.StackOverflowError。我在Hibernate社区上谷歌这个问题,但是,我不知道如何解决这个问题。请帮忙。

来自Hibernate community的回答 “我也遇到了这个无限循环问题。最终有效的解决方案是: * @IdClass *仅在“main”类中注释@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 

用户类:

@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

3 个答案:

答案 0 :(得分:1)

我认为这个问题与Hibernate无关。

如果不查看toString()Cart类中的CartItem方法,您可能需要检查这两个类中的toString()方法。

我相信您要在CartItem方法中打印Cart toString()对象,在Cart object方法中打印CartItem toString()

答案 1 :(得分:1)

通常问题出在循环关系中。首先检查equals。 hibernate使用它,不同类中的equals方法可以相互调用。所以有无限的调用,最终他们产生SO异常。第二个可能是toString。如果你在你的代码中使用它,机制将是相同的。并最终检查您的其他方法,如果它们将始终终止,即使在复杂的自引用对象图中使用

答案 2 :(得分:0)

你能否删除覆盖的方法equals和hashcode?