我有一个与此类似的数据模型:
class User { public long id; }
class UserGroup { public Set<User> members; }
class UserGroupAccess { public String access; public UserGroup userGroup; }
class Document {
public User owner;
public String publicAccess;
public Set<UserGroupAccess> userGroupAccessses;
}
逻辑是这样的:
1. If owner = user then allow access
2. If publicAccess ilike r% allow access
3. If on of the userGroupAccesses have access ilike r%
AND the user is in the userGroup attached to it, then allow access
我目前的查询是:
criteria.createAlias( "userGroupAccesses", "u" );
Disjunction root = Restrictions.disjunction();
root.add( Restrictions.ilike( "publicAccess", "r%" ) );
root.add( Restrictions.eq( "owner", currentUser ) );
Conjunction ugAccess = Restrictions.conjunction();
ugAccess.add( Restrictions.ilike( "u.access", "r%" ) );
root.add( ugAccess );
criteria.add( root );
这几乎给了我我想要的,期待检查附加到你的用户组是否包含当前用户。
我一直在尝试不同的方法,例如:
criteria.createAlias( "u.userGroup.members", "member" );
ugAccess.add( Restrictions.eq("member", currentUser) );
但这不起作用。
有什么想法我应该在这里调查吗?
更新:使用 JB Nizet 概述的方法,我得到了这个:
criteria.createAlias( "userGroupAccesses", "u" );
criteria.createAlias( "u.userGroup", "ug" );
criteria.createAlias( "ug.members", "member" );
Disjunction root = Restrictions.disjunction();
root.add( Restrictions.ilike( "publicAccess", "r%" ) );
root.add( Restrictions.eq( "user", currentUser ) );
Conjunction ugAccess = Restrictions.conjunction();
ugAccess.add( Restrictions.ilike( "u.access", "r%" ) );
ugAccess.add( Restrictions.eq( "member.uid", currentUser.getUid() ) );
root.add( ugAccess );
criteria.add( root );
这似乎有效,但它实际上删除了 or 的前两个部分,因此它仅适用于连词内的内容。
这里的正确方法是什么?我需要拆分成子查询吗?
解决了:
criteria.createAlias( "userGroupAccesses", "u", JoinType.LEFT_OUTER_JOIN );
criteria.createAlias( "u.userGroup", "ug", JoinType.LEFT_OUTER_JOIN );
criteria.createAlias( "ug.members", "member", JoinType.LEFT_OUTER_JOIN );