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

发布于 2024-08-12 13:04:21 字数 941 浏览 2 评论 0原文

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

Category category = new Category(); 
category.setName('catName');
category.setId(1L);
categoryDao.saveOrUpdate(category);

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

org.hibernate.StaleStateException:
Batch update returned unexpected row count from update [0]; actual row count: 0; 
expected: 1:

这是我的类别类设置器、获取器和构造函数,为了清楚起见,省略了:

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

在控制台中我看到这个休眠查询:

update
    Category
set
    name=?,
    parent_id=?
where
    id=?

所以看起来休眠尝试更新记录而不是插入新记录。我在这里做错了什么?

I'm try to insert or update db record with following code:

Category category = new Category(); 
category.setName('catName');
category.setId(1L);
categoryDao.saveOrUpdate(category);

When there is a category with id=1 already in database everything works. But if there is no
record with id=1 I got following exception:

org.hibernate.StaleStateException:
Batch update returned unexpected row count from update [0]; actual row count: 0; 
expected: 1:

Here is my Category class setters, getters and constructors ommited for clarity:

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

In the console I see this hibernate query:

update
    Category
set
    name=?,
    parent_id=?
where
    id=?

So looks like hibernates tryis to update record instead of inserting new. What am I doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

感悟人生的甜 2024-08-19 13:04:21

这是设计使然。

Hibernate 仅根据 id 决定是否应该执行更新或插入。如果它考虑数据库中已有的内容,则必须执行额外的查询,但它不会这样做。

Id 通常由 Hibernate 管理,除非您将其映射为 generator="assigned" (不知道使用注释看起来如何)。所以你不应该只给它赋值。

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

如果您想生成自己的 Id,请使用 generator="assigned",并使用 merge 存储它。这将执行您所期望的操作:它在数据库中搜索记录,当存在时它将更新它,当不存在时它将插入它。

This is by design.

Hibernate only decides based on the id if it should perform an update or an insert. If it would consider what's already there in the database, it would have to perform an additional query, but it doesn't do this.

Ids are normally managed by Hibernate, unless you map it as generator="assigned" (don't know how this looks using annotations). So you shouldn't just assign a value to it.

In this case, the Id is even given by the database. So if your application would generate Ids at the same time, it would result in duplicated Ids. (And most database do not allow inserting values to auto columns, so it would technically be impossible to store your id).

If you want to generate your own Ids, use generator="assigned", and store it using merge. This will do what you expect: it searches the record in the database, when it exists it will update it, when not it will insert it.

梦情居士 2024-08-19 13:04:21

如果表的行数为 0,请尝试单独使用 save 方法,否则使用 saveorupdate 方法。

try to use save method alone if the rowcount of the table is 0 else use saveorupdate method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文