Ole*_*nyk 7 java database hibernate
例子:
因此,我需要找到一种方法来告诉 Hibernate“重置其 ids 缓存”,或者换句话说“强制 Hibernate 再次联系 dbms 以获取当前序列值”。
一个低级过程 [...] 插入 100 个实体 [...] id 从 1 到 100
为什么该低级过程会自行生成 ID?为什么不使用该序列?
Hibernate 的pooled 和 pooled-lo ID 生成机制的全部要点,您似乎正在使用(并且绝对应该使用,如果您没有使用),就是能够安全地缓存 ID ,即使在任何使用的外部进程上也是如此Hibernate 控制之外的序列。
如果该外部进程也使用该序列,那么您的问题就会消失,因为 Hibernate 的缓存值都不会被使用;下一批缓存的值将从外部进程最后生成的任何序列值开始,避免冲突:
sequence.NEXTVAL将会是50。sequence.NEXTVAL将是5050。sequence.NEXTVAL将是5100。假设您使用 Hibernate 的池化(-lo)ID 策略,您的问题的解决方案不是禁用或重置 Hibernate 的缓存并影响您的应用程序性能;解决方案是让任何外部进程在将数据插入该表时也使用 NEXTVAL() 为实体生成适当的 ID,而不是提供自己的值。
担忧:
“但那样我的身份证上就会出现空白!”
所以呢?
您的 ID 列中存在间隙是没有任何问题的。您的目标是避免 ID 冲突,并确保您的应用程序不会在每次创建实体时两次访问数据库(一次用于序列,一次用于实际插入)。如果为此付出的代价就是没有一组整齐、完美连续的 ID,那就这样吧!如果你问我的话,这很划算;)
“但是随后使用 Hibernate 的缓存值创建的实体的 ID 会低于之前由外部进程创建的实体!”
所以呢?
拥有 ID 列的主要目标是能够通过单个值唯一标识行。区分创建顺序不应该成为您管理 ID 值的一个因素;时间戳列更适合于此。
“但是ID值增长太快了!我刚刚插入了50行,已经有几千行了!我会用完数字的!”
好吧,这是合理的担忧。但如果您使用序列,则很可能您使用的是 Oracle 或 PostgreSQL,也可能是 SQL Server。我对吗?
嗯,PostgreSQL 的序列 MAXVALUEbigint是 9223372036854775807。SQL Server 也是如此。如果您的进程每毫秒不间断地插入一个新行,则仍需要500 万年才能到达序列末尾。Oracle 的序列 MAXVALUE 为 999999999999999999999999999,比该值大几个数量级。
所以...只要正确选择 ID 列和序列的数据类型,在这方面您就是安全的。
lap*_*ets -1
您是否尝试过清除当前会话并创建一个新会话?这会强制 Hibernate 重新查询数据库以获取当前序列值。
换句话说,您可以使用该方法Session.flush()和Session.clear():
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
// Perform some operations that use the id cache
session.flush();
session.clear();
// Perform some more operations that use the id cache
transaction.commit();
session.close();
Run Code Online (Sandbox Code Playgroud)
或者您可以使用EntityManager.refresh()它将从数据库刷新实例的状态,并在此过程中使用当前序列值更新内部缓存:
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
// Perform some operations that use the id cache
em.refresh(entity);
// Perform some more operations that use the id cache
em.getTransaction().commit();
em.close();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1147 次 |
| 最近记录: |