收藏表的Hibernate标准查询? [英] Hibernate criteria query for Collection Table?

查看:85
本文介绍了收藏表的Hibernate标准查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体

  @Entity 
@Table(name =rule)
public class Rule实现Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name =rule_id)
private Long ID;
$ b @ElementCollection(targetClass = Action.class)


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

//根据jbrookover的建议编辑后,添加一个新的映射
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name =rule_id )
私人设置< RuleAction> ruleActions;


}

以下是我的动作

  public enum动作{
PHONE,EMAIL,POSTAL,PHONE_OR_EMAIL,SMS;

$ / code>

我想获取一个具有特定操作集的规则列表
我试过这个

  DetachedCriteria criteria = DetachedCriteria.forClass(Rule.class,rule); 
criteria = criteria.createAlias(rule.actions,action);
criteria.add(Restrictions.in(action.name,actionSet));
return getHibernateTemplate()。findByCriteria(criteria);

但是获取
org.hibernate.MappingException:集合不是关联:异常..

编辑
因此,在jbrookover的指导下,我尝试着为包装类命名为RuleAction,并能够eshtablish oneToMany关系,我也修改了如下查询:

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

DetachedCriteria标准= DetachedCriteria.forClass(Rule.class);
criteria.add(Restrictions.eq(SUPPORT_LANG,Language.valueOf(EN)))
.createCriteria(ruleActions).add(Restrictions.in(action,act));
return getHibernateTemplate()。findByCriteria(criteria);

但是,这是返回给我的所有规则有EMAIL或POSTAL,但我想要的是所有使用EMAIL和POSTAL的规则请帮助我修改查询。

解决方案

对不起,您正在尝试做,具体来说,在Hibernate中不受支持。查看常见问题解答:

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;





然后,更新你的关联并进行相应的查询,使得规则有一个设置< ActionWrapper> 。还有其他的解决方法,但你基本上不能同时使用 Criteria @ElementCollection



更新

为了进一步限制查询,为了确保您获得符合BOTH操作的规则,需要运行子查询并执行匹配值的连接 - '和'。像这样的东西应该可以工作:

 标准subCriteria = criteria.createCriteria(ruleActions); 
Disjunction和= Restrictions.conjunction();
for(Action a:act)
and.add(Restrictions.eq(action,a)
subCriteria.add(and);


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

  criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 



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


I have following Entity

@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;


    }

Following is my Action

public enum Action {
    PHONE, EMAIL, POSTAL,PHONE_OR_EMAIL, SMS;
}

I want to fetch a List of rule having particular set of actions I am trying this

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

But getting org.hibernate.MappingException: collection was not an association: exception..

EDIT So after guidance from jbrookover I tried going for a wrapper class for Action named as RuleAction and was able to eshtablish the oneToMany relationship, Also I modified the query as follows

    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);

But this is returning me all the rule which are having either EMAIL or POSTAL but what I want is all the rule having EMAIL and POSTAL both Please help me in modifying the query.

解决方案

Sorry, what you are trying to do, specifically, is not supported in Hibernate. See this 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

I, too, was quite displeased with this. As you can see, though, they've tried to fix it an have been unable to do so and have put it on the community to deal with it. You have a few options:

  1. Use HQL to run the query.
  2. Re-write your collection association as an actual entity class with a single Enum field.

You can do something like this:

 @Entity
 public class ActionWrapper {

      public Action action;
 }

Then, update your associations and query accordingly so that Rule has a Set<ActionWrapper>. There are other workarounds, but you essentially cannot use Criteria and @ElementCollection together.

Update

In order to restrict the query further, to ensure that you get Rules that meet BOTH actions, you need to run the subquery and do a conjunction - 'and' - of the matched values. Something like this should work:

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

At the end, you may find duplicate results. This is common and can be eliminated by adding this:

 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

I can't speak for the efficiency of this code - HQL may be better in the long run. However, I've done something similar in other projects and haven't encountered any issues.

这篇关于收藏表的Hibernate标准查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆