java - 使用休眠更新记录的正确方法是什么,更改不会反映在数据库中?
问题描述
我有以下映射:
<hibernate-mapping>
<class name="com.jurnil.db.hibernate.Order" table="order_table">
<id name="id" type="long" column="id">
<generator class="identity"/>
</id>
<property name="shippingTotal">
<column name="shipping_total" not-null="false"/>
</property>
<one-to-one name="shippingInfo" class="com.jurnil.db.hibernate.OrderShipping" cascade="all">
</one-to-one> </class>
</hibernate-mapping>
我正在尝试从数据库中检索现有的“订单”,按顺序修改一些值并将它们更新回数据库。
以下是我拥有的 DAO 方法:
public boolean updateOrder(Order o) {
Session s = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = getTransaction(s);
o.setUpdated(new Date());
s.saveOrUpdate(o);
tryCommit(tx);
return true;
我打电话给orderDAO.updateOrder(order);
更改未反映在数据库中,并且在休眠日志中我可以看到Duplicate entry '332' for key 'PRIMARY'
当我尝试将会话重写updateOrder
为
Session s = HibernateUtil.getSessionFactory().openSession();
s.saveOrUpdate(o);
给我以下错误,Duplicate entry '332' for key 'PRIMARY'
在尝试了@Guillaume 的建议之后
改变DAO方法:
public boolean updateOrder(BigDecimal cartTotal, OrderShipping shippingInformation, BigDecimal taxes,
BigDecimal orderTotal, BigDecimal shippingTotal, Long id) {
Session s = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = getTransaction(s);
Order order = (Order) s.load(Order.class, id);
order.setCartTotal(cartTotal);
order.setShippingInfo(shippingInformation);
order.setTaxPaid(taxes);
order.setTotalPaid(orderTotal);
order.setShippingTotal(shippingTotal);
order.getShippingInfo().setOrder(order);
order.setUpdated(new Date());
tryCommit(tx);
return true;
}
数据库中的数据仍未更新,在 SQL 日志中我可以看到事务正在回滚,为什么会发生这种情况?
下面是 SQL 日志
[2020-09-17 17:45:44,125] DEBUG org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader - Done entity load : com.jurnil.db.hibernate.Order#335
[2020-09-17 17:45:44,126] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - committing
[2020-09-17 17:45:44,126] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Processing flush-time cascades
[2020-09-17 17:45:44,135] DEBUG org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 335, using strategy: org.hibernate.id.ForeignGenerator
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.jurnil.db.hibernate.OrderShipping#335]
[2020-09-17 17:45:44,136] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - rolling back
解决方案
您的Order
对象需要与您用于事务的会话相关联。例如,如果您想使用 id #322 更新订单:
Session s = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = getTransaction(s);
Order o = s.load(Order.class, 322);
o.setUpdated(new Date());
tryCommit(tx);
注意saveOrUpdate
被删除:当事务提交时,Hibernate 会看到 Order 被修改并更新数据库。
推荐阅读
- c# - 将 Linq var 行追加到 dataTable c#
- magento - Shopify 和 Magento 1 实时同步库存
- database - 只读角色的 Postgres 默认权限
- reactjs - 当客户端在 Docker 中时,Crud React spring-boot 应用程序返回 404
- php - 致命错误:指令“asp_tags” - 在 Windows 10 中使用命令提示符 PHP 安装作曲家
- java - 如何在java selenium中将屏幕截图附加到范围报告
- php - PHP:有条件插入
- spring-security - Spring 反应式安全 - 类型 javax.servlet.Filter 不存在
- java - 仅知道目录的相对路径时如何读取目录中的文件
- scala - 如何使用 list.collect 或 list match 来获取正确的数据