@OneToMany 映射列表大小限制

发布于 2024-12-12 01:53:46 字数 227 浏览 0 评论 0原文

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

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

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

对你的占有欲 2024-12-19 01:53:46

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

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

您可以验证该集合。

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

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

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

You could validate the collection.

@OneToMany(mappedBy = "publication", cascade=CascadeType.PERSIST)
@Size(min=1, max=10)
private List<Comment> commentList;
酷遇一生 2024-12-19 01:53:46

真正的问题是集合本身。您不应该以这种方式为您的业务领域建模。此解决方案(使用 @OneToMany 注释的集合)仅适用于小型集合(数十个对象),而不适用于大型集合(数千个对象),这很可能是带有注释的情况。你真的必须小心他们,因为他们很快就会失控。我目前仅使用它们来建模与 Account 关联的 Role 集合,因为我知道在我的域中任何帐户都不会拥有超过 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;
}

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

要进行分页,只需 setFirstResult 到与以下内容对应的第一个结果
您想要显示的页面。 EG 显示结果 20 .. 29,您可以调用
setFirstResult(20)

The real problem is the collection itself. You should not model 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.

Instead of adding a collection of comments to your object, add a reference to the object on Comment and explicitly get the comments you want using a query.

Define a named query on Comment to get the comments for a certain object (let's use 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.setMaxResults and Query.setFirstResult to explicitly control how many results to get and allow for paging etc:

@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 setFirstResult to the first result corresponding with
the page you want to display. E.G. to show results 20 .. 29, you would call
setFirstResult(20).

倦话 2024-12-19 01:53:46

您无法在 JPA 中执行此操作,而且它没有意义,因为映射旨在反映关系中存在多少对象的实际情况。

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

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

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

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

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

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.

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

*correction: @Batchsize is a Hibernate feature

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

瞳孔里扚悲伤 2024-12-19 01:53:46

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文