限制JPA中集合的大小

说我有这样的实体

@Entity Class A{ //fields @Onetomany Set b; // } 

现在,我如何限制集合中’B’的数量,使得当集合中有新条目时,最旧的条目被删除,有些像我们在LinkedHashMap中有的removeEldestEntry 。

我正在使用带有Hibernate的MySQL 5.5 DB。 提前致谢。

编辑

我的目标是在任何时间点都不要在该表中包含超过N个条目。 我的一个解决方案是使用Set并安排作业来删除旧条目。 但我发现它很脏。 我正在寻找一个更清洁的解决方案。

我会使用代码手动强制执行此规则。 主要思想是集合B应该被很好地封装,使得客户端只能通过公共方法(即addB() )来改变其内容。 只需在此方法( addB() )中确保此规则,以确保集合B内的条目数不能大于值。

A:

 @Entity public class A { public static int MAX_NUM_B = 4; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) private Set b= new LinkedHashSet(); public void addB(B b) { if (this.b.size() == MAX_NUM_B) { Iterator it = this.b.iterator(); it.next(); it.remove(); } this.b.add(b); } public Set getB() { return Collections.unmodifiableSet(this.b); } } 

B:

 @Entity public class B{ @ManyToOne private A a; } 

要点:

  • A应该是关系的所有者。
  • 在A中,不要简单地返回B,因为客户端可以绕过addB addB(B b)实现的检查逻辑并自由地更改其内容。相反,返回B的不可修改的视图。
  • 在@OneToMany中,将orphanRemoval设置为true,告诉JPA在从B集合中删除相应的实例后删除B的DB记录。

Apache Commons Collection提供了一个API。 在这里你可以使用CircularFifoBuffer类来引用你遇到的同样问题,如果你想要如下所示的例子你可以实现

 Buffer buf = new CircularFifoBuffer(4); buf.add("A"); buf.add("B"); buf.add("C"); buf.add("D"); //ABCD buf.add("E"); //BCDE 

我想你必须手动完成它。

想到的一个解决方案是在实体A使用@PrePersist@PreUpdate事件侦听器。

在使用上述注释注释的方法中,检查Set大小,如果它高于最大限制,则删除最旧的B条目(可以通过B的created_time timestamp属性跟踪)