忽略条件中的休眠获取

Posted

技术标签:

【中文标题】忽略条件中的休眠获取【英文标题】:Hibernate fetching in criteria ignored 【发布时间】:2014-11-08 13:56:37 【问题描述】:

我有一些类 User 与 LoginSession 类有一对多的关系(我的 User 类中有一组 LoginSessions)。

@Entity(name="T_User")
public class User() 

   ....
     @OneToMany(fetch=FetchType.LAZY, mappedBy="user", cascade=CascadeType.ALL)
     @Fetch(FetchMode.SELECT)
     @JsonIgnore
     private Set<LoginSession> userLoginSession;
   ....
 

这里是 LoginSession 类:

@Entity(name="T_LoginSession")
public class LoginSession extends BasicDTO


    @ManyToOne
    @JoinColumn(name="userId")  
    protected User user;
    ...

我有这个标准:

Criteria crit = session.createCriteria(User.class);
crit.setFetchMode("loginSession", FetchMode.JOIN);
crit.createAlias("userLoginSession", "session");
crit.add(Restrictions.eq("session.token", sessionToken));
crit.setMaxResults(1);
crit.setFirstResult(0);
crit.setFetchSize(1);

问题是获取总是惰性的。我怎样才能使它成为 Eager(通过标准而不是通过属性注释)?

注意: 如果我在private Set&lt;LoginSession&gt; userLoginSession 上方添加@Fetch 注释,则在注释中设置的响应获取(我不会按照标准setFetchMode 对其进行自定义)。

字段名称(setFetchMode 方法的第一个参数)是否正确?

问题: Is this bug related to my issue?

【问题讨论】:

查看***.com/questions/25823552/… @Killer,我看不出它对我有什么帮助 【参考方案1】:

试试:

 Criteria crt = session.createCriteria(User.class);
 crt.setFetchMode("sessions", FetchMode.JOIN);

【讨论】:

条件标准 = session.createCriteria(User.class); criteria.setFetchMode("会话", FetchMode.JOIN); List list = criteria.list(); docs.jboss.org/hibernate/orm/3.3/reference/en/html/…【参考方案2】:

尝试关注

Criteria crit = session.createCriteria(User.class);
crit.setFetchMode("session.userId", FetchMode.EAGER);
User myThingy = (User)crit.uniqueResult();

【讨论】:

EAGER 已弃用,根据文档我需要使用 JOIN。 好的,你是得到了意想不到的结果还是一些异常。怎么了?你是如何测试你的代码的? setFetchingMethod 什么都不做。那就是问题所在。我看到在获取用户时有一个查询(如代码中所示),在访问关系时有另一个查询。 你是否使用注解进行映射? 是的,你可以在问题中看到【参考方案3】:

尝试在别名上设置连接类型:

Criteria crit = session.createCriteria(User.class);
crit.createAlias("userLoginSession", "session", Criteria.INNER_JOIN);
crit.add(Restrictions.eq("session.token", sessionToken));
crit.setMaxResults(1);
crit.setFirstResult(0);
crit.setFetchSize(1);

【讨论】:

不推荐使用 :( 什么被弃用了?在稳定版中,可以使用 createAlias(String associationPath, alias, joinType) (docs.jboss.org/hibernate/stable/core/javadocs/org/hibernate/…, java.lang.String, org.hibernate.sql.JoinType)) 我使用的是休眠 4,而 Eclipse 表明它已被弃用。你能看看我作为字符串提供给 setFetchingMethod 的名称吗?【参考方案4】:

如here 所述,您不能同时过滤和急切获取集合。您可以使用相关子查询来解决它:

DetachedCriteria subquery = DetachedCriteria.For(User.class)
    .createAlias("userLoginSession", "session")
    .add(Restrictions.eq("session.token", sessionToken))
    .setFirstResult(0)
    .setMaxResults(1)     // assuming token is unique otherwise this won't restrict users but loginsessions
    .setProjection(Projections.id());

Criteria crit = session.createCriteria(User.class)
    .add(Subqueries.propertyIn("id", subquery)
    .setFetchMode("userLoginSession", FetchMode.JOIN);

注意:这是我头顶的文本编辑器代码。方法名可能不同

【讨论】:

以上是关于忽略条件中的休眠获取的主要内容,如果未能解决你的问题,请参考以下文章

休眠条件中日期的限制

带有投影和限制的休眠条件查询问题

使用休眠仅从对象中的表中获取选定的列

具有嵌入对象的实体的休眠条件

如何使用休眠条件仅返回对象的一个​​元素而不是整个对象?

使用 Hibernate 中的条件按月分组