I'm quite confused, I'm trying to find out why I'm getting the creation of two Customers in the database with the following code with no luck. I tried to cut all the noise from the code, I hope I didn't erased anything important for the resolution of the problem. Here are in the following order : Entities, DAOs, Services and the SpecialService with the specialTreatment which holds the bogus behavior.
In the specialTreatment the aim is to get an existing Order with no Customer linked to it, create a new Customer, and associate it to the order.
Entities :
Order.java :
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "pk_id_order")
private Integer id;
// Other fields ...
@BatchFetch(value = BatchFetchType.IN)
@JoinColumn(name = "fk_id_customer", referencedColumnName = "pk_id_customer")
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Customer customer;
// Other fields ...
// Getter & setters for each field
@Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Order)) {
return false;
}
final Order other = (Order) obj;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
return false;
}
return true;
}
}
Customer.java :
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "pk_id_customer")
private Integer id;
// Other fields
@OrderBy(value = "createdAt DESC")
@OneToMany(mappedBy = "customer", fetch = FetchType.LAZY)
private List<Order> orders;
@Override
public int hashCode() {
return (id != null ? id.hashCode() : 0);
}
@Override
public boolean equals(Object object) {
if (object == null || !(object instanceof Customer)) {
return false;
}
final Customer other = (Customer) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
}
DAOs :
@Repository
@Transactional
public class CustomerDao {
@PersistenceContext
protected EntityManager em;
public void create(Customer customer) {
this.em.persist(customer);
}
}
@Repository
@Transactional
public class OrderDao {
@PersistenceContext
protected EntityManager em;
public Order edit(Order order) {
return this.em.merge(order);
}
}
Services :
@Service
@Transactional
public class CustomerService {
@Autowired
private CustomerDao customerDao;
public void create(Customer customer) {
this.customerDao.create(customer);
}
}
@Service
@Transactional
public class OrderService {
@Autowired
private OrderDao orderDao;
public void edit(Order order) {
this.orderDao.edit(order);
}
}
@Service
@Transactional
public class SpecialService {
@Autowired
private CustomerService customerService;
@Autowired
private OrderService orderService;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void specialTreatment(Order order) {
Customer customer = new Customer();
// Fill customer ...
this.customerService.create(customer); // LINE X
order.setCustomer(customer); // LINE Y
this.orderService.edit(order);
}
}
Note : When commenting line X : - There is no customer created (as expected), the order is edited as expected When commenting line Y : - The customer is created as expected (only one row) but it is not linked to my Order
The code is called from a Spring MVC controller
Any advice ?