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