Hibernate saveOrUpdate() 更新时创建新条目
Posted
技术标签:
【中文标题】Hibernate saveOrUpdate() 更新时创建新条目【英文标题】:Hibernate saveOrUpdate() creates new entry when updating 【发布时间】:2017-11-29 00:17:23 【问题描述】:我创建了一个名为“gauge_category”的表,它只有一个字段“gauge_category_id”作为主键,数据类型为varchar。我尝试了 CRUD 操作。创建、读取、删除操作完美运行。当我更新时,它正在创建一个新条目,而不是更新。我从一些文章中了解了 saveOrUpdate() 。单击编辑按钮时从 URL 传递的参数正常工作。
但我注意到我尝试了另一个类,它有两个字段 id(int)(primarykey) ,college(Varchar)。当 id add <form:hidden path="id" />
以 jsp 形式添加时,此处更新正确。
saveOrUpdate() 执行以下操作:
如果对象已在此会话中持久存在,则不执行任何操作 如果与会话关联的另一个对象具有相同的标识符,则抛出异常 如果对象没有标识符属性,则保存()它 如果对象的标识符具有分配给新实例化对象的值,则保存()它 如果对象由 or 版本化,并且版本属性值与分配给新的值相同 实例化对象,保存()它 否则更新()对象
模型类
@Entity
@Table(name = "gauge_category")
public class GaugeCategory
@Id
@Column(name = "gauge_category_id", unique = true, nullable = false)
private String category;
public GaugeCategory()
super();
public GaugeCategory(String category)
super();
this.category = category;
public String getCategory()
return category;
public void setCategory(String category)
this.category = category;
Dao 实现类
//other methods, @Autowired
@Override
public void saveOrUpdate(GaugeCategory GaugeCategory)
sessionFactory.getCurrentSession().saveOrUpdate(GaugeCategory);
控制器类
//other methods, @Autowired
@RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView saveCategory(@ModelAttribute("gaugeCategoryForm") GaugeCategory gaugeCategory)
gaugeCategoryService.saveOrUpdate(gaugeCategory);
return new ModelAndView("redirect:/gaugeCategory/list");
用于添加的jsp页面
<spring:url value="/gaugeCategory/save" var="saveURL"></spring:url>
<form:form action="$saveURL " modelAttribute="gaugeCategoryForm">
<form:input path="category" />
</form:form>
【问题讨论】:
如果表只有一个字段,则无法将旧 id 获取到update
。如果旧 id 是例如1,如果您只有一个字段,则将其更改为 2,则无法检测旧值 1 来执行更新。因此创建了一个新实例。如果有多个字段 id (PK) 和一些数据字段,则该 id 用于执行更新。
我们是否需要在所有表中始终包含 id (INT)?
【参考方案1】:
问题是您的模型只有一个字段并且它是主键。当您尝试更新实体时,您会更改表单中键的值,因此 hibernate 不知道它应该更新哪个实体,而是创建一个新实体。
另外,只有一个字段的模型的目的是什么?最好有一些实体,例如:
@Entity
@Table(name = "gauge_category")
public class GaugeCategory
@Id
@GeneratedValue
private Integer id;
@Id
@Column(name = "name", unique = true, nullable = false)
private String name;
// ...
拥有这样的实体,您将能够使用 id 更新类别的名称,并在其他数据库表中引用该 id。如果您使用字符串外键,则很难更新其他表,尤其是在它们有很多记录的情况下。
【讨论】:
所以你建议我拥有多个领域,不是吗?我得到了你的解释。我的疑问是,如果我有两个数据类型为 varchar 的字段,一个是主键,会发生什么?这个问题也一样。或者我们是否至少需要数据类型为 INT 的 id? @varman 是的,我建议您使用一个INT
和一个VARCHAR
字段,有关更多详细信息,请参阅this answer 了解为什么最好使用代理整数键。
非常感谢您提供的建议。我已经完成了整数 ID。以上是关于Hibernate saveOrUpdate() 更新时创建新条目的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate中saveOrUpdate()和merge()的区别
关于hibernate的saveOrUpdate方法的一个问题
jooq中hibernate的saveOrUpdate方法的等价物是啥?
hibernate save,update,saveorupdate方法有什么区别