gpt4 book ai didi

java - 强制具有 AllocationSize 的 TableGenerator 跳到下一个间隔

转载 作者:太空宇宙 更新时间:2023-11-04 07:28:08 24 4
gpt4 key购买 nike

我有一个 JPA 实体,其 TableGenerator 的 AllocationSize=25。如果我手动更新 TableGenerator 表并为其下一个 ID 起始范围指定一个新值,则在当前范围过去之前它不会产生任何效果。

例如,如果当前 TableGenerator 表值为 10,我将开始获取实体 ID 250、251、252 等。在 255 时,我将 TableGenerator 表值更改为 20。但是,下一个 ID 仍将是 256、257,一直到 274,那么下一个 ID 将为 500。

当然,这是很自然的 - 但我想知道,有没有办法告诉 Hibernate 此时忽略当前间隔并开始从 TableGenerator 表中的任何内容分配 ID?

<小时/>

因此,就我的具体情况而言,要回答重要的原因:

我正在为我团队的产品开发一个测试自动化工具,一方面,它能够通过正在运行的系统(使用客户端应用程序、API 等)设置测试数据。测试数据配置(我们称之为测试数据)的定义使得多个测试数据可以一起用于特定的测试用例/测试套件。

现在,一旦运行了测试数据,该工具将从数据库中提取输入的数据到 SQL 插入语句中,并将它们存储到文件中。造成这种情况的原因有很多,但主要与性能有关 - 如果我想使用某个测试数据运行 100 个测试用例,我只关心测试数据“手动”插入一次,然后每次重置时,我可能会采取更快的方式将测试数据直接插入数据库。

但是,正如我所说,多个测试数据可以一起使用。如果 testdata01 和 testdata02 都影响同一个表怎么办?如果事先已经运行了另一个 SQL 插入语句,则提取的 SQL 插入语句将不会仅包含该特定测试数据的数据。

对此的一个简单解决方案是为每个测试数据保留一个 ID 间隔。对于每个表,testdata01 的区间为 [10000, 20000),testdata02 的区间为 [20000, 30000) 等。这很容易实现 - 在运行每个测试数据之前,只需将所有 TableGenerator 表更新为测试数据的 ID 间隔的下限 - 然后,在运行测试数据设置之后,仅提取 ID 在间隔内的行。

这非常有效,并确保测试数据之间的 ID 永远不会发生任何冲突,并且每个测试数据的导出 SQL 仅包含该特定测试数据的数据,而不管当时数据库中可能还有什么数据。然而,allocationSize 不为 1 的这一件事使事情变得困惑 - 条目可能仍然出现在给定实体的保留 ID 间隔之外,即使我们已经更新了该实体的 TableGenerator。

所以,简而言之,我想做的是,在更新 TableGenerator 表之后、开始运行测试数据设置之前,我想告诉 Hibernate 对于每个实体,下次生成 ID 时,忽略您想要从该 TableGenerator 的范围生成的任何下一个值,而是检查数据库中的 TableGenerator 表以了解下一个要使用的范围。

最佳答案

所以我自己设法刮掉了这个。如果有人有相同的需求,供将来引用:

public void moveToNextInterval(Class entity, javax.persistence.EntityManager em) throws IllegalAccessException, InstantiationException {
javax.persistence.TableGenerator tableGenerator = null;
for (Method method : entity.getMethods()) {
tableGenerator = method.getAnnotation(javax.persistence.TableGenerator.class);
if (tableGenerator != null) {
break;
}
}
if (tableGenerator != null && tableGenerator.allocationSize() > 1) {
int allocationSize = tableGenerator.allocationSize();
org.hibernate.impl.SessionImpl session = (org.hibernate.impl.SessionImpl) em.unwrap(org.hibernate.Session.class);
IdentifierGenerator idGenerator = session.getFactory().getIdentifierGenerator(entity.getName());
while ((Long)idGenerator.generate(session, entity.newInstance()) % allocationSize != allocationSize - 1);
}
}

还不太习惯 Hibernate 或 JPA,所以可能还有很多可能的改进。对于任何类型的序列生成器来说,推广这一点应该不会太困难。此外,您可能只需要创建一个实体实例并重用它。此外,我认为存在超出预期 ID 的风险;例如,如果 allocateSize=25 并且最后一个 ID 为 24,并且我们已更新 TableGenerator 表并将其设置为 10,则调用此方法实际上将使其下一个 ID 为 275,而不是 250。对于我的目的而言,这已经足够好了,但很高兴知道。

关于java - 强制具有 AllocationSize 的 TableGenerator 跳到下一个间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18206688/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com