为什么Criteria API会引发StackOverFlow异常?

时间:2020-07-30 13:53:54

标签: java hibernate jpa

我有2个实体,它们之间是一对一的关系:客户和购物车。客户是购物车的所有者,因此FK列是指向购物车PK的客户表。

这是购物车类:

@Entity
@Table(name = "testCart_cart")
public class Cart {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cart_id", unique = true, nullable = false)
    private long id;

    @OneToMany(cascade = CascadeType.ALL,
            orphanRemoval = true,
            fetch = FetchType.LAZY)
    @JoinColumn(name = "cart_id")
    private List<CartItem> listOfCartItems;

    @OneToOne(mappedBy = "cart",
            fetch = FetchType.LAZY)
    private Customer customer;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public List<CartItem> getListOfCartItems() {
        return listOfCartItems;
    }

    public void setListOfCartItems(List<CartItem> listOfCartItems) {
        this.listOfCartItems = listOfCartItems;
    }

    public void setCustomer(Customer customer) { this.customer = customer; }

    public Customer getCustomer() { return customer; }

    @Override
    public String toString() {
        return "Cart{" +
                "id=" + id +
                ", listOfCartItems=" + listOfCartItems +
                ", customer=" + customer +
                '}';
    }
}

这是我的客户类:

@Entity
@Table(name = "testCart_customer")
public class Customer implements Serializable {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @Column(name = "id", unique = true, nullable = false)
    private long id;

    @Column(name = "username", unique = true, nullable = false)
    private String username;

    @OneToOne(cascade = CascadeType.ALL,
            fetch = FetchType.LAZY)
    @JoinColumn(name = "cart_id")
    private Cart cart;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Cart getCart() {
        return cart;
    }

    public void setCart(Cart cart) {
        this.cart = cart;
    }

    @Override
    public String toString() {
        return "Costumer name: " + username;
    }
}

因此,我使用Criteria API而不是JPQL(对我来说更容易)。
这是我的代码:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Cart> query = cb.createQuery(Cart.class);
Root<Customer> customer = query.from(Customer.class);
ParameterExpression<String> strignParameter = cb.parameter(String.class);
Join<Customer, Cart> carts = customer.join("cart");
query.select(carts).where(cb.equal(customer.get("username"),name));
Cart cart = entityManager.createQuery(query).getSingleResult();

return cart;

这在控制台中:

Exception in thread "main" java.lang.StackOverflowError
    at org.hibernate.query.sqm.tree.domain.AbstractSqmAttributeJoin.getNodeJavaTypeDescriptor(AbstractSqmAttributeJoin.java:71)
    at org.hibernate.query.sqm.tree.domain.SqmSingularJoin.getJavaTypeDescriptor(SqmSingularJoin.java:52)
    at org.hibernate.query.sqm.tree.domain.AbstractSqmAttributeJoin.getNodeJavaTypeDescriptor(AbstractSqmAttributeJoin.java:71)
    at org.hibernate.query.sqm.tree.domain.SqmSingularJoin.getJavaTypeDescriptor(SqmSingularJoin.java:52)
    at org.hibernate.query.sqm.tree.domain.AbstractSqmAttributeJoin.getNodeJavaTypeDescriptor(AbstractSqmAttributeJoin.java:71)
    at org.hibernate.query.sqm.tree.domain.SqmSingularJoin.getJavaTypeDescriptor(SqmSingularJoin.java:52)

总共有1024个呼叫。
尝试了来自多个来源的不同方法,并尝试与调试器一起查看正在发生的事情,机器人并没有真正解释。当调试器从 query.select ... 跳转到购物车... 时,引发错误。

1 个答案:

答案 0 :(得分:1)

当您要购物车时,为什么要从客户开始。

尝试以下方法:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Cart> query = cb.createQuery(Cart.class);
Root<Cart> cart = query.from(Cart.class);
ParameterExpression<String> strignParameter = cb.parameter(String.class);
Join<Cart, Customer> customer = cart.join("customer");
query.select(cart).where(cb.equal(customer.get("username"), name));
Cart cart = entityManager.createQuery(query).getSingleResult();