限制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属性跟踪)
- NoSuchBeanDefinitionException如何初始化SessionFactory bean?
- 无法将java.lang.Integer字段设置为java.lang.Integer
- 如何连接hibernate和DB2
- Hibernate:在同一个应用程序中使用两个不同的DataBase模式
- 使用Hibernate / JPA和JDK Date进行不需要的自动时区转换
- 自JPA 2.1以来如何命名ManyToOne引用的外键约束?
- Spring启动+ Spring数据JPA +二级缓存给出mutate错误
- 注入自动连接的依赖项失败; 嵌套exception是org.springframework.beans.factory.BeanCreationException:
- 缺少工件javax.transaction:jta:jar:1.0.1B(问题不同,因为您可能会看到分辨率不同)