Java 优化hibernate条件查询,使其更具动态性

Java 优化hibernate条件查询,使其更具动态性,java,hibernate,Java,Hibernate,我正在使用一个带有大量条件的hibernate条件查询。查询是否需要由应用程序状态和角色组成的采购申请表。为了保持简单,所有表单都是在状态1或草稿中启动的。保存表单时,当前用户将成为创建者。创建者可以将其他用户分配给表单,例如授权人或联系人。这些是我认为的动态角色。我的前三种状态如下所示 State 1 "Draft" role Creator State 2 "Authorizer" role Authorizer State 3 "Contact" role Contact 离开状态3并进

我正在使用一个带有大量条件的hibernate条件查询。查询是否需要由应用程序状态和角色组成的采购申请表。为了保持简单,所有表单都是在状态1或草稿中启动的。保存表单时,当前用户将成为创建者。创建者可以将其他用户分配给表单,例如授权人或联系人。这些是我认为的动态角色。我的前三种状态如下所示

State 1 "Draft" role Creator
State 2 "Authorizer" role Authorizer
State 3 "Contact" role Contact
离开状态3并进入状态4后,应用程序现在进入管理员角色。在最终批准和关闭表格之前,可能有多达15个州。直到最后四个状态,创建者、授权者和联系人将继续具有访问权限。最后四个州,他们将无法访问

除非管理员是创建者、授权人或联系人,否则用户将无法访问前三个状态,但将继续访问最后一个状态,包括非管理员也无法访问的其余四个状态

我当前的查询如下所示,但是作为管理员,我希望不必手动硬编码要添加到查询中的每个应用程序状态,并添加所有应用程序状态,但排除管理员不是动态角色创建者、授权人或联系人的状态

这个查询有效,但非常混乱

Disjunction programRoles = Restrictions.disjunction();
            programRoles.add(Restrictions.eq(Role.ROLE_CREATOR, user));
            programRoles.add(Restrictions.eq(Role.ROLE_AUTHORIZER, user));
            programRoles.add(Restrictions.eq(Role.ROLE_CONTACT, user));

            if(roleManagerService.isAdmin()) {
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.ARCHIVED.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.ASSESSOR_REVIEW.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.ASSIGNOR_REVIEW.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.AUDITOR_REVIEW.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.BURIED.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.DEAD.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.FINAL.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.FINAL_MAJOR_APPROVAL.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.FINAL_MINOR_APPROVAL.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.IFAS_LOAD.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.PO_COLLECTION.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.PO_DISTRIBUTION.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.PO_EVALUATION.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.PURGE.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.SECONDARY_MAJOR_REVIEW.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.SECONDARY_MINOR_REVIEW.name()));
                programRoles.add(Restrictions.eq("currentState.prStateCode", ApplicationStateEnum.SECONDARY_OVERHEAD_REVIEW.name()));
            }

        Criteria results = this.session.createCriteria(PurchaseRequest.class)
                .createAlias("currentState", "currentState")
                .add(programRoles);

                if(!roleManagerService.isAdmin()) {
                    results.add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.DEAD.name()))
                            .add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.ARCHIVED.name()))
                            .add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.FINAL.name()))
                            .add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.BURIED.name()));
                }

我想知道是否有人能给我指出一个方向,让它更具活力

我没有真正尝试过,但可能只是添加了管理员用户不允许看到的限制。 比如:

Disjunction programRoles = Restrictions.disjunction();
programRoles.add(Restrictions.eq(Role.ROLE_CREATOR, user));
programRoles.add(Restrictions.eq(Role.ROLE_AUTHORIZER, user));
programRoles.add(Restrictions.eq(Role.ROLE_CONTACT, user));

// change starts here
if(roleManagerService.isAdmin()) {
    Conjunction notHiddenStateForAdmin = Restrictions.conjunction();
    notHiddenStateForAdmin.add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.FIRST_STATE.name()));
    notHiddenStateForAdmin.add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.SECOND_STATE.name()));
    notHiddenStateForAdmin.add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.THIRD_STATE.name()));
    programRoles.add(notHiddenStateForAdmin);
}

// rest unchanged
Criteria results = this.session.createCriteria(PurchaseRequest.class)
       .createAlias("currentState", "currentState")
       .add(programRoles);

if(!roleManagerService.isAdmin()) {
     results.add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.DEAD.name()))
            .add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.ARCHIVED.name()))
            .add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.FINAL.name()))
            .add(Restrictions.ne("currentState.prStateCode", ApplicationStateEnum.BURIED.name()));
}

向RoleManager服务询问集合候选应用程序状态()和集合排除应用程序状态()是否有效?然后,您只需执行一个Restrictions.in或循环来添加ne。您可能会从尝试将这种逻辑放入一个类中获得一些好处,该类知道它们是否是admin,并且可以做出决定。尽量限制布尔值的范围。@roby,我可以这样做,但所有这些状态都保存在数据库中,可以动态地进行添加/减去,所以我希望不必硬编码任何状态。我几乎在想,除了前三个状态中不包含当前用户的结果外,必须有一种方法返回admin的所有结果。Klein-Robbenha你的解决方案唯一的问题是,一旦我们越过第三个状态进入第四个状态,它只会提供包含我作为创建者、授权人或联系人的结果。一旦进入第四个状态,我将需要与所有用户一起查看它,因此,例如,如果John doe是创建者、授权人和联系人,我不应该看到他是否处于这些状态,但是一旦表单脱离这些状态,我应该将结果作为管理员查看。我唯一应该看到这些状态的结果的时候是我是否被分配到其中一个状态。好的,回到绘图板。。。嗯,我没有创建一个新的答案,而是编辑了我的原始答案,这样它现在只从管理员那里过滤“禁止”的初始状态(不确定三个名字是什么,所以它们是第一个状态…等等)。希望这个效果更好。(顺便说一句,我应该创建一个新的答案,而不是编辑一个?我不知道什么是正确的行为,因为我在这里是非常新的)谢谢,到目前为止,它似乎是工作。今天下午,我将通过我们的测试人员进行测试。如果没有bug,我会投票给你最好的答案。谢谢你的帮助。