我正在使用Criteria API和JPA的Hibernate实现 . 我想改进生成的SQL查询的结构,以便不为每个OR谓词重复相同的IN表达式 .

我想这样做是因为代码在GAE上运行,并且在IN条件中名称列表很长的情况下我得到StackOverflowError(这是由于Hibernate使用StringBuilder来构建参数列表) . 我已经将问题归结为这部分代码,就像我删除了8个OR谓词时代码运行没有错误 . 代码在非内存限制性环境(我的PC)上正常运行....是的,我已经增加了GAE上的实例内存分配,但我仍然得到相同的错误 .

我必须构建查询的这一部分的Java代码如下(参数名称已编辑,我使用@StaticMetamodel类作为参数名称): -

private void buildNamesToQuery(List<String> names, Root<ARoot> theRoot,
        Join<Entity1, Entity2> aJoin, List<Predicate> orPredicates) {

    orPredicates.add(aJoin.get(Entity1_.name1).in(names));
    orPredicates.add(aJoin.get(Entity1_.name2).in(names));
    orPredicates.add(aJoin.get(Entity1_.name3).in(names));
    orPredicates.add(aJoin.get(Entity1_.name4).in(names));

    orPredicates.add(theRoot.get(Entity2_.name5).in(names));
    orPredicates.add(theRoot.get(Entity2_.name6).in(names));
    orPredicates.add(theRoot.get(Entity2_.name7).in(names));
    orPredicates.add(theRoot.get(Entity2_.name8).in(names));
    orPredicates.add(theRoot.get(Entity2_.name9).in(names));
    orPredicates.add(theRoot.get(Entity2_.name10).in(names));
}

这将生成具有以下结构的SQL(编辑参数名称): -

选择
//选择的大量细节
哪里
//很多条件细节
//但我感兴趣的是下面的内容
和(
Entity_.name1 in(?,?,?....
)//很多名字
或(?,?,?....中的Entity_.name2
)//相同的名称列表
或者?(?,?,...中的Entity_.name3 ...
)//再次使用相同的名称列表
// .
//对于查询的其余部分//继续这样
//
);

如何更改Criteria API代码以使SQL成为这个?: -

和(
joinEntity_.name1或joinEntity.name2或joinEntity.name3 ...等IN(?,?,?...)

有相同长的名单?希望这足以让你提出一个解决方案 .