[英]Limit the size of a collection in JPA
Say I have an entity like this 说我有这样的实体
@Entity
Class A{
//fields
@Onetomany
Set<B> b; //
}
Now, how do I limit the number of 'B's in the collection in such a way that, when there is a new entry in the collection, the oldest one is removed, some thing like removeEldestEntry we have in a LinkedHashMap. 现在,我如何限制集合中'B'的数量,使得当集合中有新条目时,最旧的条目被删除,有些像我们在LinkedHashMap中有的removeEldestEntry 。
I am using MySQL 5.5 DB with Hibernate. 我正在使用带有Hibernate的MySQL 5.5 DB。 Thanks in advance.
提前致谢。
EDIT 编辑
My goal is not to have more than N number of entries in that table at any point of time. 我的目标是在任何时间点都不要在该表中有超过N个条目。 One solution I have is to use a Set and schedule a job to remove the older entries.
我的一个解决方案是使用Set并安排作业来删除旧条目。 But I find it dirty.
但我发现它很脏。 I am looking for a cleaner solution.
我正在寻找一个更清洁的解决方案。
There is one API provided by Apache Commons Collection . Apache Commons Collection提供了一个API。 Here you can use the class CircularFifoBuffer for your reference of the same problem you have, if you want example shown as below that you can achive that
在这里你可以使用CircularFifoBuffer类来引用你遇到的同样问题,如果你想要如下所示的例子你可以实现
Buffer buf = new CircularFifoBuffer(4);
buf.add("A");
buf.add("B");
buf.add("C");
buf.add("D"); //ABCD
buf.add("E"); //BCDE
I would use the code to manually enforce this rule. 我会使用代码手动强制执行此规则。 The main idea is that the collection B should be well encapsulated such that client only can change its content by a public method (ie
addB()
) . 主要思想是集合B应该被很好地封装,使得客户端只能通过公共方法(即
addB()
)来改变其内容。 Simply ensure this rule inside this method ( addB()
) to ensure that the number of entries inside the collection B cannot larger than a value. 只需在此方法(
addB()
)中确保此规则,以确保集合B内的条目数不能大于值。
A: 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: B:
@Entity
public class B{
@ManyToOne
private A a;
}
Main points: 要点:
addB(B b)
and change its content freely.Instead , return an unmodifiable view of B . addB(B b)
实现的检查逻辑并自由地更改其内容。相反,返回B的不可修改的视图。 orphanRemoval
to true to tell JPA to remove the B 's DB records after its corresponding instances are removed from the B collection. orphanRemoval
设置为true以告诉JPA在从B集合中删除相应的实例后删除B的DB记录。 I think you will have to do it manually. 我想你必须手动完成它。
One solution that comes to mind is using @PrePersist
and @PreUpdate
event listeners in entity A
. 想到的一个解决方案是在实体
A
使用@PrePersist
和@PreUpdate
事件侦听器。
Within the method annotated with above annotations , you check if size of Set<B>
, if it is above the max limit, delete the oldest B entries(which may be tracked by a created_time
timestamp property of B) 在使用上述注释注释的方法中,检查
Set<B>
大小,如果它高于最大限制,则删除最旧的B条目(可以通过B的created_time
timestamp属性跟踪)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.