2

I'm struggling to save multiple records to database with Hibernate. I don't open sessions or start transactions manually, and I'd love to avoid doing that if possible. My Service class looks like this:

@Service
@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private ProductRepository productRepository;
    @Autowired 
    private OrderRepository orderRepository;
    @Autowired
    private CartService cartService;
    @Autowired
    private OrderDetailsRepository orderDetailsRepository;


...

public void saveOrder(Order order) {
        Cart cart=order.getCart();
        order.setTotalPrice(cart.getGrandTotal());
        OrderDetails od = new OrderDetails();
        od.setOrder(order);

        for (Map.Entry<Integer, CartItem> entry : cart.getCartItems().entrySet())
        {
            Product product = entry.getValue().getProduct();
            od.setProduct(product);
                od.setQuantity(entry.getValue().getQuantity());
            od.setUnitPrice(product.getUnitPrice());
            orderDetailsRepository.save(od);
        }

        cartService.delete(order.getCart().getCartId());
    }
...

}

Now, everytime I run save method, i'd like to save one record to database, however in current state it saves only the last item ( I guess it commits transaction only at the end) Sql output:

Hibernate: 
    insert 
    into
        Orders
        (CustomerID, OrderDate, ShippingDate, TotalPrice) 
    values
        (?, ?, ?, ?)
Hibernate: 
    insert 
    into
        OrderDetails
        (OrderID, ProductID, Quantity, UnitPrice) 
    values
        (?, ?, ?, ?)
Hibernate: 
    update
        OrderDetails 
    set
        OrderID=?,
        ProductID=?,
        Quantity=?,
        UnitPrice=? 
    where
        OrderDetailsID=?

My repository class doesn't do anything besides calling persist method.

Is it possible to save multiple records to database in Hibernate while using Transactional annotation? I'd like to keep this annotation in my service class.

1 Answer 1

3

Try to move your OrderDetails declaration to carItems loop:

 public void saveOrder(Order order) {
        Cart cart=order.getCart();
        order.setTotalPrice(cart.getGrandTotal());

        for (Map.Entry<Integer, CartItem> entry : cart.getCartItems().entrySet())
        {
            OrderDetails od = new OrderDetails();
            od.setOrder(order);

            Product product = entry.getValue().getProduct();
            od.setProduct(product);
            od.setQuantity(entry.getValue().getQuantity());
            od.setUnitPrice(product.getUnitPrice());
            orderDetailsRepository.save(od);
        }

        cartService.delete(order.getCart().getCartId());
    }
...

}

In your original code, what Hibernate does is:

  • In first iteration it saves OrderDetails entity which was declared before loop (and generates id for it)
  • In every other iteration it updates the same existing entity (inserted in first iteration)

You need separate entity instances if you want to persist them as separate db records.

Sign up to request clarification or add additional context in comments.

2 Comments

Wow, I don't know what diffrence it makes but it worked, thank you mate ! :)
I've edited my answer, hope it put some light on the subject :)

Your Answer

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.