收集表的Hibernate条件查询?

Anu*_*pta 8 hibernate hibernate-criteria

我有以下实体

@Entity
@Table(name = "rule")
public class Rule implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "rule_id")
    private Long id;

    @ElementCollection(targetClass = Action.class)


     @CollectionTable(name = "rule_action", joinColumns = @JoinColumn(name = "rule_id"))
        @Enumerated(value = EnumType.STRING)
        @Column(name = "action")
        private Set<Action> actions;

//After editing as per jbrookover's suggestion adding a new mapping
       @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
       @JoinColumn(name = "rule_id")
       private Set<RuleAction> ruleActions;


    }
Run Code Online (Sandbox Code Playgroud)

以下是我的行动

public enum Action {
    PHONE, EMAIL, POSTAL,PHONE_OR_EMAIL, SMS;
}
Run Code Online (Sandbox Code Playgroud)

我想获取一个规则列表,其中包含我正在尝试此操作的特定操作集

 DetachedCriteria criteria = DetachedCriteria.forClass(Rule.class,"rule");
 criteria = criteria.createAlias("rule.actions", "action");
 criteria.add(Restrictions.in("action.name",actionSet));
 return getHibernateTemplate().findByCriteria(criteria);
Run Code Online (Sandbox Code Playgroud)

但是获取org.hibernate.MappingException:集合不是一个关联:exception ..

编辑 所以在jbrookover的指导下,我尝试了一个名为RuleAction的Action的包装类,并且能够eshtablish oneToMany关系,我修改了查询如下

    Set<Action> act = new HashSet<Action>();
    act.add(Action.EMAIL);
    act.add(Action.POSTAL);

    DetachedCriteria criteria = DetachedCriteria.forClass(Rule.class);
    criteria.add(Restrictions.eq(SUPPORT_LANG, Language.valueOf("EN")))
            .createCriteria("ruleActions").add(Restrictions.in("action",act));
    return getHibernateTemplate().findByCriteria(criteria);
Run Code Online (Sandbox Code Playgroud)

但是这回到了我所有的规则,有EMAIL或POSTAL但我想要的是所有的规则有EMAIL和POSTAL两个请帮我修改查询.

jbr*_*ver 6

抱歉,Hibernate不支持您要执行的操作.看这个FAQ:

http://community.jboss.org/wiki/HibernateFAQ-AdvancedProblems#Im_getting_orghibernateMappingException_collection_was_not_an_association_when_I_try_to_join_a_collection_of_components_with_Criteria_queries

我也对此感到非常不满.然而,正如你所看到的那样,他们已经尝试修复它已经无法做到这一点并且已经把它放在社区来处理它.你有几个选择:

  1. 使用HQL运行查询.
  2. 使用单个Enum字段将您的集合关联重写为实际实体类.

你可以这样做:

 @Entity
 public class ActionWrapper {

      public Action action;
 }
Run Code Online (Sandbox Code Playgroud)

然后,相应地更新您的关联和查询,以便Rule有一个Set<ActionWrapper>.还有其他的解决办法,但你基本上不能使用Criteria@ElementCollection在一起.

更新

为了进一步限制查询,为了确保获得满足BOTH操作的规则,您需要运行子查询并对匹配的值进行连接 - "和".这样的事情应该有效:

 Criteria subCriteria = criteria.createCriteria("ruleActions");
 Disjunction and = Restrictions.conjunction();
 for (Action a : act)
    and.add(Restrictions.eq("action", a)
 subCriteria.add(and);
Run Code Online (Sandbox Code Playgroud)

最后,您可能会发现重复的结果.这很常见,可以通过添加以下内容来消除:

 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
Run Code Online (Sandbox Code Playgroud)

我不能代表这段代码的效率 - 从长远来看,HQL可能会更好.但是,我在其他项目中做过类似的事情并没有遇到任何问题.