Hibernate - 在一个事务中保存多个对象

时间:2016-08-22 10:43:15

标签: java spring hibernate jpa transactions

我正在努力用Hibernate将多个记录保存到数据库中。我不打开会话或手动启动交易,我希望尽可能避免这样做。我的服务类看起来像这样:

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

}

现在,每次运行save方法时,我都想将一条记录保存到数据库,但是在当前状态下它只保存最后一项(我猜它只在最后提交事务)Sql输出:

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=?

除了调用persist方法之外,我的存储库类没有做任何事情。

使用Transactional注释时,是否可以在Hibernate中将多个记录保存到数据库?我想在我的服务类中保留这个注释。

1 个答案:

答案 0 :(得分:1)

尝试将OrderDetails声明移至carItems循环:

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

}

在原始代码中,Hibernate的作用是:

  • 在第一次迭代中,它保存了在循环之前声明的OrderDetails实体(并为其生成了id)
  • 在每次其他迭代中,它都会更新相同的现有实体(在第一次迭代中插入)

如果要将它们作为单独的db记录保存,则需要单独的实体实例。