【问题标题】:How to filter the size of @OneToMany collection by a given criteria如何按给定条件过滤@OneToMany 集合的大小
【发布时间】:2015-04-24 10:56:24
【问题描述】:

看这个简单的例子:

@Entity
@Table(name = "message")
public class Message implements Serializable {

    @Id
    @GeneratedValue
    private Long              id;

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn
    private User              author;

    @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE })
    private Set<Rating>       ratings;

    [...]
}

有没有办法通过过滤集合元素来限制ratings 的大小。我只想加载那些不超过 30 天的评分。

这样我从数据库中加载消息

public Message getMessageById(Serializable id) {
    Session session = _sessionFactory.getCurrentSession();
    return session.get(Message.class, id);
}

【问题讨论】:

  • @VladMihalcea 它不是重复的。我想按条件限制大小
  • 感谢您的澄清。那么请检查我的答案。

标签: java mysql spring hibernate jpa


【解决方案1】:

终于成功了。

解决方案:

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE })
@Where(clause = "DATEDIFF(NOW(), date) <= 30")
private Set<Rating>       ratings;

来自Mysql docs

DATEDIFF() 返回 expr1 - expr2,表示为从一个日期到另一个日期的值。 expr1 和 expr2 是日期或日期和时间表达式


  • 我也尝试了Vlad Mihalcea 的解决方案,但出现异常:

    原因:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:你的SQL语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的“30 rating1_.DAY) 和 rating0_.message_id=63”附近使用正确的语法

  • StanislavL 的解决方案有效,但前提是您激活了过滤器:

    Session session = sessionFactory.getCurrentSession();
    Filter filter   = session.enableFilter("minAge");
    [...]
    session.disableFilter("minAge");
    

使用@Where注解更简单,因为它不需要激活。

【讨论】:

    【解决方案2】:

    将@Filter 注释添加到您的

    @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE })
    private Set<Rating>       ratings;
    

    这样

    @FilterDef(name="minAge", parameters=@ParamDef( name="age", type="integer" ) )
    @Filters( {
        @Filter(name="minAge", condition=":age<= 30")
    } )
    

    查看更多here

    【讨论】:

    • 请注意,此解决方案仅在使用的 JPA 提供程序是 Hibernate 时才有效。
    【解决方案3】:

    这时你需要使用@Where注解:

    @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(cascade = { 
        CascadeType.PERSIST, 
        CascadeType.MERGE, 
        CascadeType.REMOVE 
    })
    @Where("time_created < NOW() - INTERVAL 30 DAY")
    private Set<Rating> ratings = new HashSet<>();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-31
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 2020-09-23
      • 2016-12-20
      • 1970-01-01
      相关资源
      最近更新 更多