4

假设我有这样的实体

@Entity
Class A{
//fields

@Onetomany
Set<B> b; // 
}

现在,我如何限制集合中“B”的数量,以便当集合中有新条目时,删除最旧的条目,例如我们在 LinkedHashMap 中的removeEldestEntry 。

我将 MySQL 5.5 DB 与 Hibernate 一起使用。提前致谢。

编辑

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

4

3 回答 3

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);
    }
}

乙:

@Entity 
public class B{

    @ManyToOne
    private A a;
}

要点:

  • A 应该是关系的所有者。
  • 在 A 中,不要简单地返回 B,因为客户端可以绕过其中实现的检查逻辑addB(B b) 并自由更改其内容。相反,返回 B 的不可修改视图。
  • 在 @OneToMany 中,设置orphanRemoval为 true 以告诉 JPA 在从 B 集合中删除其相应实例后删除 B 的 DB 记录。
于 2012-12-23T07:23:30.757 回答
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
于 2012-12-23T06:46:03.763 回答
1

我认为您将不得不手动执行此操作。

想到的一种解决方案是在 entity 中使用@PrePersist事件@PreUpdate侦听器A

在使用上述注释注释的方法中,您检查 的大小Set<B>,如果它超过最大限制,则删除最旧的 B 条目(可能由created_timeB 的时间戳属性跟踪)

于 2012-12-23T06:38:14.697 回答