Home > front end >  java.lang.StackOverflowError while saving JPA entities
java.lang.StackOverflowError while saving JPA entities

Time:07-22

I am using Spring JPA to save entities into a database. Below is code structure

Customer.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);
        }
    }
}

Order.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;
}

Now I am trying to save customer along with its orders in database like below

OrderService.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);
}

When this.customerRepository.save(customer); statement executes then I get following exception

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]
......

If I comment order.setCustomer(this); line in Customer#add(order), then error disappears but in database the customer_id is not save in order table.

I am not sure what I am doing wrong.

CodePudding user response:

@Data annotation generates equals and hashCode methods relying on entity fields. When you placing order into Customer#orders, HashSet tries to compute hashCode of Order, Order refers to Customer which in turn refers to Customer#orders - that is why you are getting SO, basically you just need to correctly define equals and hashCode methods and do not rely on lombok magic.

Using Primiry Key (id) while overriding equals() and hashCode() methods

  • Related