spring-data-jpa 保存JPA实体时发生java.lang.StackOverflowError

8wigbo56  于 2022-11-10  发布在  Spring
关注(0)|答案(2)|浏览(246)

我正在使用SpringJPA将实体保存到数据库中。

客户.java

@Entity
@Table(name="customer")
@Data
public class Customer {

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

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
    private Set<Order> orders = new HashSet<>();

    public void add(Order order) {
        if(order != null) {
            if(orders == null) {
                this.orders = new HashSet<>();
            }
            this.orders.add(order);
            order.setCustomer(this);
        }
    }
}

订单.java

@Entity
@Table(name="order")
@Data
public class Order {

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

    @ManyToOne
    @JoinColumn(name = "customer_id")
    private Customer customer;
}

现在,我正在尝试将客户沿着订单保存在数据库中,如下所示

订单服务.java

@Transactional
public PurchaseResponse placeOrder(Purchase purchase) {

    Order order = purchase.getOrder();

    String orderTrackingNumber = UUID.randomUUID().toString();
    order.setOrderTrackingNumber(orderTrackingNumber);

    Customer customer = purchase.getCustomer();
    customer.add(order);

    this.customerRepository.save(customer);

    return new PurchaseResponse(orderTrackingNumber);
}

this.customerRepository.save(customer);语句执行时,我得到以下异常

java.lang.StackOverflowError: null
at com.ecomhunt.entities.Order.hashCode(Order.java:15) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.ecomhunt.entities.Customer.hashCode(Customer.java:11) ~[classes/:na]
at com.ecomhunt.entities.Order.hashCode(Order.java:15) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.ecomhunt.entities.Customer.hashCode(Customer.java:11) ~[classes/:na]
at com.ecomhunt.entities.Order.hashCode(Order.java:15) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.ecomhunt.entities.Customer.hashCode(Customer.java:11) ~[classes/:na]
......

如果我在Customer#add(order)中注解order.setCustomer(this);行,则错误消失,但在数据库中,customer_id未保存在order表中。
我不知道我做错了什么。

uubf1zoe

uubf1zoe1#

@Data注解会根据实体字段产生equalshashCode方法。当您将order放入Customer#orders时,HashSet会尝试计算OrderhashCodeOrder会指涉Customer,而Customer又会指涉Customer#orders-这就是您会得到SO的原因。基本上,您只需要正确定义equalshashCode方法,而不需要依赖于lombok魔术。
Using Primiry Key (id) while overriding equals() and hashCode() methods

vbopmzt1

vbopmzt12#

我发现@Data注解的隐式toString特性导致了StackOverFlow错误。
删除@Data注解并显式定义要改为使用的方法,例如getter和setter方法

相关问题