0

I have a customer json like below

{
 "id": "id",
 "name": "full name",
 "products": [{
 "id": "pid1",
 "productName": "productName",
 "xBenefits": [{
 "id": "p1-xbid1",
 "name": "benefit name"
 },{
 "id": "p1-xbid2",
 "name": "benefit name"
 }],
 "yBenefits": [{
 "id": "p1-ybid1",
 "name": "benefit name"
 },{
 "id": "p1-ybid2",
 "name": "benefit name"
 }],
 "zBenefits": [{
 "id": "p1-zbid1",
 "name": "benefit name"
 },{
 "id": "p1-zbid2",
 "name": "benefit name"
 }]
 },{
 "id": "pid2",
 "productName": "productName",
 "xBenefits": [{
 "id": "p2-xbid1",
 "name": "benefit name"
 },{
 "id": "p2-xbid2",
 "name": "benefit name"
 }],
 "yBenefits": [{
 "id": "p2-ybid1",
 "name": "benefit name"
 },{
 "id": "p2-ybid2",
 "name": "benefit name"
 }],
 "zBenefits": [{
 "id": "p2-zbid1",
 "name": "benefit name"
 },{
 "id": "p2-zbid2",
 "name": "benefit name"
 }]
 }]
}

The corresponding entity classes like below

public class Customer {
 String id;
 String name;
 List<Product> products;
}
public class Product {
 String id;
 String productName;
 List<XBenefit> xBenefits;
 List<YBenefit> yBenefits;
 List<ZBenefit> zBenefits;
}
public class XBenefit {
 String id;
 String name;
}
public class YBenefit {
 String id;
 String name;
}
public class ZBenefit {
 String id;
 String name;
}

We are using mybatis xml mapper files to insert the records into the tables. Below is some sample service code which does the inserts

@Service
public class CustomerServiceImpl implements CustomerService {
 @Autowired
 private ProductService productService;
 
 @Autowired
 private CustomerMapper customerMapper;
 
 @Override
 @Transactional
 public void save(Customer customer) {
 customerMapper.save(customer);
 
 productService.save(customer.getProducts());
 }
}
@Service
public class ProductServiceImpl implements ProductService {
 
 @Autowired
 private ProductMapper productMapper;
 
 @Autowired
 private XBenefitService xBenefitService;
 
 @Autowired
 private YBenefitService yBenefitService;
 
 @Autowired
 private ZBenefitService ZBenefitService;
 
 @Override
 @Transactional
 public void save(List<Product> products) {
 
 for (Product product: products) {
 productMapper.save(product)
 xBenefitService.save(product.getXBenefits());
 yBenefitService.save(product.getYBenefits());
 zBenefitService.save(product.getZBenefits());
 }
 }
}
@Service
public class XBenefitServiceImpl implements XBenefitService {
 
 @Autowired
 private XBenefitMapper xBenefitMapper;
 
 @Override
 @Transactional
 public void save(List<XBenefit> xBenefits) {
 xBenefits.forEach(xBenefit -> {
 xBenefitMapper.save(xBenefit);
 });
 }
}

So far everything works good. If a row fails to insert, all the rows inserted thus far are are also rolled back. We have integration tests written for this.

However I think there is a room for improvement here. Once a Product is inserted, I think I can safely insert the corresponding benefits simultaneously. However I am not sure of how to do this using spring @Async and also in the same transaction so that if a benefit fails to insert the entire transaction rolls back.

I did some research on google and gemini AI results are not consistent across searches on my desktop and mobile.

I want the main method to wait until all the products and associated benefits are inserted successfully and then complete. Something like rxjx's forkjoin.

Can anyone please shed some light here, point me to a step by step guide if one exists somewhere over the web? Thanks much.

asked Apr 29, 2025 at 15:18

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.