持久/合并上的 JPA 树值传播
Posted
技术标签:
【中文标题】持久/合并上的 JPA 树值传播【英文标题】:JPA tree value propagation on persist/merge 【发布时间】:2014-09-27 10:52:24 【问题描述】:我有
@Entity
public class Node
@ManyToOne
private Node parent;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Node> children;
@ManyToMany
private List<Owner> ownerList;
...
我想将owner
s 传播给坚持/合并的孩子。规则是:
Any node must have at least its parent node owners
我试过了
@PreUpdate
public void propagateOwnersTopDown(Node node)
for(Node child : node.getChildren())
for(Owner owner : node.getOwnerList())
if(!child.getOwnerList().contains(owner))
child.getOwnerList().add(owner);
还有一个
@PreUpdate
public void propagateOwnersBottomUp(Node node)
if(node.getParent() == null) return;
for(Owner owner : node.getParent().getOwnerList())
if(!node.getOwnerList().contains(owner))
node.getOwnerList().add(owner);
即使我知道这是不合法的,事实上,这些都不起作用(@PreUpdate
仅在根上调用)。
我知道我可以
编写一个addOwner()
方法将所有者传播给孩子
但如果一些其他代码调用node.getOwnerList().add(owner)
传播被破坏
或
显式调用propagateOwnersTopDown()
或em.merge(node)
之前的类似名称(通常在事务中)
但我必须将此添加到每个 EJB/事务方法中
我想知道是否有一些巧妙的方法可以做到这一点。
我不是数据库专家,但是否有可能实现与存储过程/触发器/任何东西的一致性?
如果为真,是否可以/合法地调用@PrePersist
/@PreUpdate
中的过程/触发器/任何东西?
我正在使用 EclipseLink 2.5.2 和 mysql 5.6
谢谢。
【问题讨论】:
EclipseLink 2.5.2 具有 JPA 2.1。 你是对的。谢谢。 【参考方案1】:我实现了自己的 Listener 子系统:
protected <T extends AbstractEntity> void invokeListeners(T entity, Class<? extends Annotation> annotation)
ServiceListeners serviceListeners = entity.getClass().getAnnotation(ServiceListeners.class);
if(serviceListeners != null)
try
for(Class<?> listenerClass : serviceListeners.value())
Object instance = listenerClass.newInstance();
Set<Method> methods = ReflectionUtils.getAllMethods(listenerClass, ReflectionUtils.withAnnotation(annotation));
for(Method m : methods)
m.invoke(instance, entity);
catch(Exception e)
throw new RuntimeException(e.getMessage(), e);
public <T extends AbstractEntity> void create(T entity)
invokeListeners(entity, OnCreate.class);
em.persist(entity);
public <T extends AbstractEntity> T update(T entity)
invokeListeners(entity, OnUpdate.class);
T entity2 = em.merge(entity);
em.flush();
em.refresh(entity2);
return entity2;
【讨论】:
以上是关于持久/合并上的 JPA 树值传播的主要内容,如果未能解决你的问题,请参考以下文章