Java Hibernate saveOrUpdate()在更新时创建新条目

Java Hibernate saveOrUpdate()在更新时创建新条目,java,mysql,spring,hibernate,jsp,Java,Mysql,Spring,Hibernate,Jsp,我创建了一个名为“gauge\u category”的表,它只有一个字段“gauge\u category\u id”,它是主键,数据类型是varchar。我试过积垢手术。创建、读取和删除操作工作正常。当我更新时,它正在创建一个新条目,而不是更新。我从一些文章中了解了saveOrUpdate()。单击“编辑”按钮时从URL传递的参数工作正常 但我注意到我尝试了另一个类,它有两个字段id(int)(primarykey),college(Varchar)。当id以jsp形式另外添加时,更新工作正常

我创建了一个名为“gauge\u category”的表,它只有一个字段“gauge\u category\u id”,它是主键,数据类型是varchar。我试过积垢手术。创建、读取和删除操作工作正常。当我更新时,它正在创建一个新条目,而不是更新。我从一些文章中了解了saveOrUpdate()。单击“编辑”按钮时从URL传递的参数工作正常

但我注意到我尝试了另一个类,它有两个字段id(int)(primarykey),college(Varchar)。当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;
    }   
}
//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");
    }
Dao实现类

@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;
    }   
}
//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");
    }
控制器类

@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;
    }   
}
//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>

问题在于您的模型只有一个字段,并且它是主键。当您试图更新实体时,您会更改表单中键的值,因此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更新类别的名称,并在其他DB表中引用该id。如果使用字符串外键,则很难更新其他表,尤其是当它们有大量记录时。

对于只有一个字段的表,无法获取旧id以更新
。如果旧id为1,并且您将其更改为2,如果您只有一个字段,则无法检测旧值1以执行更新。这样就创建了一个新实例。如果有多个字段id(PK)和一些数据字段,则该id用于执行更新。我们是否需要在所有表中始终使用id(INT)呢?因此,您建议我使用多个字段,不是吗?我明白你的解释了。我的疑问是,如果我有两个数据类型为varchar的字段,一个是主键,会发生什么?这个问题也一样。或者我们需要至少一个数据类型为INT的id吗?@varman是的,我建议您使用一个
INT
和一个
VARCHAR
字段,有关为什么使用代理整数键更好的更多详细信息,请参阅。非常感谢您提供的建议。我已经完成了整数id。