我在空表上执行时,Hibernate saveOrUpdate失败

Vla*_*mir 3 hibernate save

我尝试使用以下代码插入或更新db记录:

Category category = new Category(); 
category.setName('catName');
category.setId(1L);
categoryDao.saveOrUpdate(category);
Run Code Online (Sandbox Code Playgroud)

当数据库中已存在id = 1的类别时,一切正常.但如果没有id = 1的记录,我得到以下异常:

org.hibernate.StaleStateException:
Batch update returned unexpected row count from update [0]; actual row count: 0; 
expected: 1:
Run Code Online (Sandbox Code Playgroud)

为清晰起见,这里是我的Category类setter,getters和constructors:

@Entity
public class Category {    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToOne
    private Category parent;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "parent")
    private List<Category> categories = new ArrayList<Category>();
}
Run Code Online (Sandbox Code Playgroud)

在控制台中我看到了这个hibernate查询:

update
    Category
set
    name=?,
    parent_id=?
where
    id=?
Run Code Online (Sandbox Code Playgroud)

所以看起来像hibernates tryis更新记录而不是插入新的.我在这做错了什么?

Ste*_*ger 5

这是设计的.

Hibernate只根据id决定是否应该执行更新或插入.如果它会考虑数据库中已有的内容,则必须执行其他查询,但它不会执行此操作.

Ids通常由Hibernate管理,除非您将其映射为generator="assigned"(不知道这看起来如何使用注释).所以你不应该只为它分配一个值.

在这种情况下,Id甚至由数据库给出.因此,如果您的应用程序同时生成ID,则会导致重复的ID.(并且大多数数据库不允许将值插入自动列,因此在技术上不可能存储您的ID).

如果您想生成自己的ID,请使用generator="assigned"并存储它merge.这将按照您的期望执行:它搜索数据库中的记录,当它存在时将更新它,否则它将插入它.