说我有这样的实体
@Entity
Class A{
//fields
@Onetomany
Set<B> b; //
}
现在,我如何以这样的方式限制集合中的'B',当集合中有新条目时,最旧的条目被移除,有些像我们所拥有的removeEldestEntry一个LinkedHashMap。
我正在使用带有Hibernate的MySQL 5.5 DB。提前谢谢。
修改
我的目标是在任何时间点都不要在该表中拥有超过N个条目。 我的一个解决方案是使用Set并安排作业来删除旧条目。但我发现它很脏。我正在寻找一个更清洁的解决方案。
答案 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;
}
要点:
addB(B b)
中实现的检查逻辑并自由更改其内容。相反,返回B的不可修改的视图。orphanRemoval
设置为true,告诉JPA在从B集合中删除相应的实例后删除B的DB记录。 答案 2 :(得分:1)
我认为你必须手动完成。
我想到的一个解决方案是在实体@PrePersist
中使用@PreUpdate
和A
个事件侦听器。
在使用上述注释注释的方法中,检查Set<B>
的大小是否超过最大限制,删除最旧的B条目(可以通过created_time
时间戳属性跟踪B)