如何在Hibernate中创建临时表?
目标
- 在 Hibernate 中调用
CREATE TEMPORARY TABLE
语句,而不使用本机 SQL。这意味着仅使用 HQL 或 Hibernate API。 - 将对象保存到临时表。
- 调用使用现有表和临时表的存储过程。
- 完成后
DROP
临时表。 (我知道没有必要,但我认为这样做是一个好习惯。)
背景
- 我对 SQL 非常熟悉,但对 Hibernate 还很陌生。
- 由于某人的决定,我被迫在项目中使用 Hibernate。
- 我要将 Web 表单保存到 Oracle 数据库。
- Web 表单包含一张充满文本字段(由其他人设计)的表格,每个单元格中都有一个。
- 当用户单击
保存
时,值必须保存在单个事务中。 - Web 表单由数据库视图支持。
- 数据库视图是使用 EAV 模式从数据库表创建的。 (这样做是因为列在某种程度上是动态的。)
- Web 表单中的每个文本字段均由数据库表中的一行建模。
- 显示 Web 表单在视图上使用
SELECT
语句。 - 更新 Web 表单在视图上使用
UPDATE
语句,该语句调用视图的INSTEAD OF
触发器。 - 仅更新更改的值。每次更新都有审核跟踪。
- 如果其他用户在未通知用户的情况下更新了任何值,则事务将回滚。以下是此类场景的示例:
(I)
当用户显示 Web 表单(II)
another 时,a 的值为4
用户将同一字段更新为5
(III)
第一个用户将该字段更新为2
并提交 Web 表单。
最初提出的解决方案
- 使用 AJAX (jQuery) 检测文本字段中的更改,并仅提交用户更改的内容。
- 但是,需要在数据库中检测到其他用户所做的更改。
解决方案应该工作得更好
- 当用户点击
保存
时,创建一个临时表(临时表是仅当前会话可见的表/连接,并在会话关闭/断开连接时自动删除)并将对象(单元格)保存到临时表中。 - 开始交易。
- 锁定一些现有表(或仅锁定相关行,以提高性能)。
- 将提交的数据与现有数据进行比较。
- 如果发生任何未被注意到的更改,请回滚事务。
- 更新必要的行。
- 提交事务并解锁表。
- 删除临时表。
有什么想法吗?
Goal
- Invoke a
CREATE TEMPORARY TABLE
statement in Hibernate without using native SQL. That means using HQL or Hibernate APIs only. - Save objects to the temporary table.
- Invoke a stored procedure which makes use of existing tables and the temporary table.
DROP
the temporary table when finished. (I know it's not necessary, but I think it's a good habit to do so.)
Background
- I'm very familiar with SQL but new to Hibernate.
- I'm forced to use Hibernate in a project because of, you know, someone's decision.
- I'm going to save a web form to an Oracle database.
- The web form contains a table full of text fields (designed by someone else), one in each cell.
- When the user clicks
Save
, the values MUST be saved in a single transaction. - The web form is backed up by a database view.
- The database view is created from a database table using the EAV pattern.
(It is done so because the columns are somehow dynamic.) - Each text field in the web form is modeled by one row in the database table.
- Displaying the web form uses
SELECT
statements on the view. - Updating the web form uses
UPDATE
statements on the view, which calls theINSTEAD OF
trigger of the view. - Only changed values are updated. There is an audit trail for each update.
- If any of the values are updated by another user without the user's notice, the transaction is rolled back. Here is an example for such a scenario:
(I)
the value of a is4
when the user displays the web form(II)
another user updates the same field to5
(III)
the first user updates the field to2
and submits the web form.
Originally Proposed Solution
- Use AJAX (jQuery) to detect changes in the text fields, and submit only those changed by the user.
- However, changes made by another user need to be detected in the database.
Solution Supposed to Work Better
- When the user clicks
Save
, create a temporary table (a temporary table is a table only seen by the current session / connection, and is dropped automatically when the session is closed / upon disconnection) and save the objects (cells) into the temporary table. - Start a transaction.
- Lock some of the existing tables (or only related rows, for performance).
- Compare the submitted data with the existing data.
- If any unnoticed change was made, rollback the transaction.
- Update the necessary rows.
- Commit the transaction and unlock the tables.
- Drop the temporary table.
Is there any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这并不能满足您的确切要求,但考虑到没有尝试给出答案...您是否考虑过使用临时 CSV 表,例如 http://csvjdbc.sourceforge.net/。
虽然它不符合通过 hibernate 执行此操作的要求,但它与数据库无关且跨平台。
This does not answer your exact requirements but given that there have been no attempts at an answer... have you considered using a temporary CSV table using something like http://csvjdbc.sourceforge.net/.
While it does not conform to requirement of doing it through hibernate, it is database agnostic and cross platform.
我认为这是使用乐观锁概念的经典场景。它是在实体中称为版本的新字段的帮助下实现的,该字段是递增的数字或时间戳。 @version 注释(在休眠中)将确保您拥有增量版本号。
这是这个概念的演练。
(I) 当用户显示 Web 表单时,a 的值为 4 - fetch
记录的版本以及其他字段。说一下版本
(II) 另一个用户将同一字段更新为 5 - 另一个用户会
将版本更改为其他数字。假设是版本 2。
(III) 第一个用户将字段更新为 2 并提交网络表单。
这样您就不会替换其他人的记录。 Hibernate 确实可以为您提供更多帮助。它捕获这种情况并抛出 OptimisticLockException,您可以使用它来做出任何异常决定。
I see it is a classic scenario to use the optimistic lock concept. It is achieved with the help of a new field in your entity called version which is an increasing number or timestamp. @version annotation (in hibernate) will ensure you have an incremental version number.
Here is a dry run of the concept.
(I) the value of a is 4 when the user displays the web form - fetch
the version of the record along with other fields. Let's say the version
(II) another user updates the same field to 5 - Another user would
change the version to some other number. Let's say Version 2.
(III) the first user updates the field to 2 and submits the webform.
This way you are not replacing someone else's record. Hibernate does help you with a little bit more here. It catches this scenario and throws an OptimisticLockException and you can use it to take any exceptional decision.