java @OneToMany 映射列表大小限制

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7894931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:52:46  来源:igfitidea点击:

@OneToMany mapping list size limit

javajpaone-to-many

提问by gus

Is there any way to limit the list's size of the @OneToMany relationship in JPA? Here's my code sample:

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

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

I'm using EclipseLink 2.3 JPA implementation. Thanks in advance.

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

回答by jeha

Part of the Bean Validation Specification (JSR-303) is the @Size(min=, max=)annotation:

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

Supported types are String, Collection, Map and arrays. Check if the annotated element size is between min and max (inclusive).

支持的类型是字符串、集合、映射和数组。检查带注释的元素大小是否介于 min 和 max (含)之间。

You could validate the collection.

您可以验证集合。

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

回答by Stijn de Witt

The real problem is the collection itself. You should notmodel your business domain this way. This solution (of collections annotated with @OneToMany) is only viable for small collections (dozens of objects) and not for large ones (thousands of objects) which may very well be the case with comments. You really have to watch out with them as they can quickly grow out of control. I am using them at the moment only to model the collection of Roles associated with an Account, because I know that no account will ever have more than 9 roles in my domain and because the roles an account is in is so very vital to working with the account. For all other m-to-n relations I am using plain old queries.

真正的问题是集合本身。你应该不会型号搜索业务领域这种方式。此解决方案(用 注释的集合@OneToMany)仅适用于小型集合(数十个对象),不适用于大型集合(数千个对象),注释很可能就是这种情况。你真的必须小心他们,因为他们很快就会失去控制。我目前仅使用它们来对Role与 an 关联的s集合进行建模Account,因为我知道在我的域中没有一个帐户会拥有超过 9 个角色,并且因为一个帐户所在的角色对于与帐户。对于所有其他 m-to-n 关系,我使用的是普通的旧查询。

Instead of adding a collection of comments to your object, add a reference to the object on Commentand explicitlyget the comments you want using a query.

与其向您的对象添加一组注释,不如添加对对象的引用,Comment并使用查询显式获取您想要的注释。

Define a named query on Commentto get the comments for a certain object (let's use Article):

定义一个命名查询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;
}

Then, use that named query i.c.w. Query.setMaxResultsand Query.setFirstResultto explicitly control how many results to get and allow for paging etc:

然后,使用该命名查询 icw 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();

To do paging, just setFirstResultto the first result corresponding with the page you want to display. E.G. to show results 20 .. 29, you would call setFirstResult(20).

做分页,只setFirstResult对要显示的页面对应的第一个结果。EG 显示结果 20 .. 29,您将调用 setFirstResult(20).

回答by Desmond Zhou

You cannot do this in JPA and it doesn't make sense because mappings are designed to reflect the reality of how many objects are in the relationship.

您不能在 JPA 中执行此操作,而且它没有意义,因为映射旨在反映关系中有多少对象的现实。

Are you doing this because of performance? If so what you can do is to use a Lazyfetch style and use the Batchsizeannotation to specific how many you want to fetch once:

你这样做是因为性能吗?如果是这样,您可以做的是使用Lazyfetch 样式并使用Batchsize注释来指定您要获取一次的数量:

*correction: @Batchsize is a Hibernate feature

*更正:@Batchsize 是一个休眠功能

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

Then in your code, simply only iterate/loop to where you want in this mapped collection.

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

Either way, from my experience "hacking" mappings to do what Criterias/Querys are designed for is not a fruitful endeavor, when you need more control or performance-tuning than the @OneToMany explicitly provides, the best way might be to just make a query.

无论哪种方式,根据我的经验,“破解”映射以执行标准/查询的设计目的并不是一项富有成效的努力,当您需要比 @OneToMany 明确提供的更多控制或性能调整时,最好的方法可能是制作一个询问。

回答by Nicolae Petridean

No real ortodox way of doing this. I would make the relation lazy, query for the parent objects. After wards do not initialize the lazy list, and run another query based on the first query, that runs on the child table. This way you can limit the result set on the main criteria and not on a join criteria. Or you can run only the second query (only on the child table), with pagination support.

没有真正的正统方式来做到这一点。我会让关系变得懒惰,查询父对象。之后病房不初始化惰性列表,并基于第一个查询运行另一个查询,该查询在子表上运行。通过这种方式,您可以将结果集限制在主要标准上,而不是在连接标准上。或者您可以仅运行第二个查询(仅在子表上),并支持分页。