当前位置: 首页 > 面试题库 >

正确使用Session.persist()

萧霍英
2023-03-14
问题内容

我正在尝试了解的语义Session.persist(),以及实体管理器对未保存的瞬态实例的确切含义。我要实现的只是向会话添加一个新的临时实例,并INSERT在刷新会话时让Hibernate执行一个。

我发现如果持久保存一个新实例,然后在同一会话中对其进行修改,则实体管理器将同时生成INSERTUPDATE语句,这可能会导致约束冲突。

例如,假设我有一个带有列 和以下服务方法的实体关系 FooNOT NULL __

@Transactional
void persistFoo(String bar) {
    Foo foo = new Foo();
    session.persist(foo);
    foo.setBar(bar);
}

尽管我们为提供了一个值bar,但是执行此代码将违反数据库中的 NULL 约束。

BatchUpdateException: Cannot insert the value NULL into column 'bar'

在Hibernate文档指出以下。

persist()使瞬态实例持久化。但是,它不能保证将标识符值立即分配给持久实例,分配可能会在刷新时发生。

INSERT该届会议在事务块结束时刷新点确实执行,但它仍然是从对象属性值参数化 ,因为它是 何时persist()被调用。

我知道可以通过一些简单的更改来解决此示例说明的特定问题,但是我对尝试理解其 如何工作更感兴趣。

我的问题是,这种行为只是合同的一部分,Session.persist()还是可以更改?如果是这样,我如何告诉会话将生成的INSERT语句的收集参数推迟到实际执行该语句之前?


问题答案:

是的,这是的合同的一部分Session.persist()。根据Hibernate文档,这是执行SQL的顺序:

  1. 按执行顺序插入
  2. 更新
  3. 删除收集元素
  4. 插入收集元素
  5. 按执行顺序删除

该顺序是官方Hibernate API的一部分,应用程序在操纵其实体图时会依赖它。

Session.persist()立即在INSERT语句后进行更改会破坏该合同,并在某些用例中引起问题。

假设我们有一个User实体,并且两个用户可能以某种方式彼此关联。然后,我们可以将两者插入一个事务中:

persist(user1);
persist(user2);
user1.setPartner(user2);
user2.setPartner(user1);

如果所有内容都存储在INSERT语句中,则在html" target="_blank">持久化时会违反外键约束user1

通常,通过确保仅传递给的状态以persist结束INSERT,Hibernate为我们提供了更大的灵活性来满足基础数据库的约束。

我不知道可以更改此行为的任何配置。当然,正如您提到的,persist只要不违反数据库约束,就可以重组代码,以便在设置所有值之后调用该代码。



 类似资料:
  • 问题内容: 我试图了解Java 8中API 的方法。 我有简单的逻辑: 但这会导致编译错误: 我当然可以做这样的事情: 但这就像混乱的支票一样。 如果我将代码更改为此: 代码变得越来越脏,这让我想到了回到旧支票。 有任何想法吗? 问题答案: 需要作为参数。您正在向其传递类型为void的表达式。因此,它不会编译。 使用者应被实现为lambda表达式: 甚至更简单,使用方法参考: 这基本上与 想法是仅

  • 问题内容: 什么时候应该从而不是从中导出例外? 不必在方法的子句中声明A ,因为它不一定要专门列出,否则可能是 好 方法,也可能是 不好的, 因为显式声明方法的异常是一种好习惯。 有什么想法吗? 问题答案: 来自未经检查的异常- 争议 : 如果可以合理预期客户端会从异常中恢复,请将其设置为已检查的异常。如果客户端无法采取任何措施来从异常中恢复,请将其设置为未经检查的异常。 请注意,未检查的异常是从

  • 问题内容: SimpleHttpConnectionManager使用不正确。确保始终调用HttpMethod.releaseConnection(),并且一次只有一个线程和/或方法正在使用此连接管理器。 是否有人知道为什么会出现此错误,并导致我要下载的文件失败或失败,然后重试或下载未完成的文件 谢谢 ! 问题答案: 确保不使用SimpleHttpConnectionManager创建和使用来自多

  • 我有一个结构如下的项目。 是我的主要应用程序,而和是导入到Project中的两个库。使用了的一些类,使用了的一些类。 在的文件中,我使用了。一切正常。但是,如果我用替换,它就不能从导入类。它给出错误。

  • 问题内容: 我的代码如下: Eclipse的此代码有两个问题: 对于那行说 对于那行说 问题答案: Apache Commons Configuration 的核心具有以下运行时依赖性: Apache Commons Lang(版本2.2、2.3、2.4、2.5或2.6) Apache Commons Collections(版本3.1、3.2或3.2.1) Apache Commons Logg

  • 问题内容: 我只想检索UserAccount类中的某些列,所以我有以下代码: 我得到了空值作为回报。但是,如果我注释掉setProjections,我将获得具有所有属性的用户。在这种情况下,如何正确使用setProjection? 问题答案: 它返回一个Object数组,因此代码应为: