如何在Hibernate中创建临时表?

7

目标

  1. 使用HQL或Hibernate API调用CREATE TEMPORARY TABLE语句,而不使用本地SQL。
  2. 将对象保存到临时表中。
  3. 调用使用现有表和临时表的存储过程。
  4. 完成后DROP临时表。(我知道这并非必要,但我认为这是一个好习惯。)

背景

  1. 我非常熟悉SQL,但对Hibernate很陌生。
  2. 由于某个人的决定,我被迫在项目中使用Hibernate。
  3. 我将一个Web表单保存到Oracle数据库中。
  4. Web表单包含一个文本字段的表格(由其他人设计),每个单元格一个。
  5. 当用户点击Save时,值必须在单个事务中保存。
  6. Web表单由数据库视图支持。
  7. 数据库视图使用EAV模式从数据库表创建。 (这样做是因为列有点动态。)
  8. Web表单中的每个文本字段由数据库表中的一行建模。
  9. 显示Web表单使用视图上的SELECT语句。
  10. 更新Web表单使用视图上的UPDATE语句,该语句调用视图的INSTEAD OF触发器。
  11. 只有更改的值会被更新。每次更新都有审计跟踪。
  12. 如果其他用户在用户没有注意到的情况下更新了任何值,则事务将被回滚。以下是此类情况的示例:(I)当用户显示Web表单时,a的值为4(II)另一个用户将相同的字段更新为5(III)第一个用户将字段更新为2并提交Web表单。

最初提出的解决方案

  1. 使用AJAX(jQuery)检测文本字段中的更改,并仅提交用户更改的内容。
  2. 但是需要在数据库中检测其他用户所做的更改。

应该更好地工作的解决方案

  1. 当用户点击保存时,创建一个临时表(临时表是仅在当前会话/连接中看到的表,并且在会话关闭/断开连接时自动删除),并将对象(单元格)保存到临时表中。
  2. 开始事务。
  3. 锁定一些现有表(或仅相关行以提高性能)。
  4. 将提交的数据与现有数据进行比较。
  5. 如果有任何未注意到的更改,则回滚事务。
  6. 更新必要的行。
  7. 提交事务并解锁表。
  8. 删除临时表。

有什么想法吗?


1
Oracle临时表在会话关闭时不会被删除。它们是永久性的。只有在会话存活期间才能看到数据。一旦会话关闭,数据就会消失,但表仍然存在。 - GLaDOS
2个回答

1

这并不完全符合您的要求,但考虑到还没有尝试回答...您是否考虑使用临时CSV表,例如http://csvjdbc.sourceforge.net/

虽然它不符合通过Hibernate执行的要求,但它是数据库无关和跨平台的。


0

我看到使用乐观锁概念是一个经典的场景。它通过在实体中添加一个名为版本的新字段来实现,该字段是递增的数字或时间戳。@version注释(在Hibernate中)将确保您拥有递增的版本号。

以下是该概念的干运行。

  1. (I)当用户显示Web表单时,a的值为4-获取记录的版本以及其他字段。假设版本为

  2. (II)另一个用户将同一字段更新为5-另一个用户将更改版本为其他数字。假设版本2。

  3. (III)第一个用户将字段更新为2并提交Web表单。

    • 在保存记录时,更新语句将如下所示-
    update user_table
    set somefield = value
    where version = 1  --(as web form contains version 1 of the record)

这样你就不会替换别人的记录了。Hibernate在这里帮了你一点忙。它会捕获这种情况并抛出一个OptimisticLockException异常,你可以利用它来做出任何特殊的决策。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接