@OneToMany映射列表大小限制

时间:2011-10-25 19:45:36

标签: java jpa one-to-many

有没有办法限制JPA中@OneToMany关系的列表大小? 这是我的代码示例:

@OneToMany(mappedBy = "publication", cascade=CascadeType.PERSIST)
private List<Comment> commentList;

我正在使用EclipseLink 2.3 JPA实现。 提前谢谢。

4 个答案:

答案 0 :(得分:15)

Bean验证规范(JSR-303)的一部分是@Size(min=, max=)注释:

  

支持的类型是String,Collection,Map和数组。检查带注释的元素大小是否在最小值和最大值(包括)之间。

您可以验证该集合。

@OneToMany(mappedBy = "publication", cascade=CascadeType.PERSIST)
@Size(min=1, max=10)
private List<Comment> commentList;

答案 1 :(得分:3)

真正的问题是收藏本身。您应该以这种方式为您的业务域建模。此解决方案(使用@OneToMany注释的集合)仅适用于小型集合(数十个对象),而不适用于大型集合(数千个对象),这些情况很可能是评论的情况。你真的要注意它们,因为它们很快就会失控。我目前正在使用它们来模拟与Role相关联的Account集合,因为我知道在我的域中没有帐户会有超过9个角色,并且因为角色是帐户对于使用该帐户非常重要。对于所有其他m-to-n关系,我使用普通的旧查询。

不是在对象中添加注释集合,而是在Comment上添加对象的引用,并在 中使用查询获取所需的注释。

Comment上定义命名查询以获取特定对象的评论(让我们使用Article):

@Entity
@NamedQueries(value={
    @NamedQuery(name=Comment.FOR_ARTICLE, query=
        "SELECT c FROM Comment c WHERE c.article = :article"
    )
})
public class Comment {
    // ...
    @ManyToOne
    @JoinColumn(name = "articleId")
    private Article article;
}

然后,使用该命名查询i.c.w. Query.setMaxResultsQuery.setFirstResult明确控制要获取和允许分页等的结果数量:

@PersistenceContext
EntityManager em;

Article theArticle = ...;

Query query = em.createNamedQuery(Comment.FOR_ARTICLE, Comment.class);
query.setParameter("article", theArticle);
query.setFirstResult(0);
query.setMaxResults(10);
List<Comment> comments = (List<Comment>) query.getResultList();

要进行分页,只需setFirstResult到与之对应的第一个结果 您要显示的页面。例如。显示结果20 .. 29,你会打电话 setFirstResult(20)

答案 2 :(得分:2)

你不能在JPA中做到这一点并且它没有意义,因为映射旨在反映关系中有多少对象的现实。

你是否因为表现而这样做?如果是这样,您可以使用 Lazy 获取样式并使用批量化注释来指定您想要获取的次数:

* 更正:@Batchsize是一个Hibernate功能

@OneToMany(mappedBy = "publication", cascade=CascadeType.PERSIST, fetch=LAZY)
@BatchSize(size=16)
private List<Comment> commentList;

然后在您的代码中,只需迭代/循环到此映射集合中的所需位置。

无论哪种方式,根据我的经验“黑客”映射来做Criterias / Querys的设计并不是一项富有成效的尝试,当你需要比@OneToMany明确提供的更多控制或性能调整时,最好的方法可能是只是进行查询。

答案 3 :(得分:0)

没有真正的正统方式这样做。 我会使关系变得懒惰,查询父对象。病毒之后不要初始化惰性列表,并根据第一个查询运行另一个查询,该查询在子表上运行。这样,您可以限制主要条件的结果集,而不是连接条件。或者您可以仅使用分页支持运行第二个查询(仅在子表上)。