限制JPA中集合的大小

时间:2012-12-23 06:25:36

标签: java mysql hibernate jpa

说我有这样的实体

@Entity
Class A{
//fields

@Onetomany
Set<B> b; // 
}

现在,我如何以这样的方式限制集合中的'B',当集合中有新条目时,最旧的条目被移除,有些像我们所拥有的removeEldestEntry一个LinkedHashMap。

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

修改

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

我会使用该代码手动强制执行此规则。主要思想是集合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> b= new LinkedHashSet<B>();

    public void addB(B b) {
        if (this.b.size() == MAX_NUM_B) {
            Iterator<B> it = this.b.iterator();
            it.next();
            it.remove();
        }
        this.b.add(b);
    }

    public Set<B> getB() {
        return Collections.unmodifiableSet(this.b);
    }
}

B:

@Entity 
public class B{

    @ManyToOne
    private A a;
}

要点:

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

答案 2 :(得分:1)

我认为你必须手动完成。

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

在使用上述注释注释的方法中,检查Set<B>的大小是否超过最大限制,删除最旧的B条目(可以通过created_time时间戳属性跟踪B)