JPA树价值传播/合并
问题描述:
@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
小号传播到孩子们在坚持/合并。规则是:
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);
}
}
}
即使我知道这是不合法的,而事实上,这些不工作(调用只在根上)。
我知道可以
- 写信
addOwner()
方法,其传播所有者儿童- 但如果一些其他的代码调用
node.getOwnerList().add(owner)
传播被捣毁
- 但如果一些其他的代码调用
或
- 显式调用
propagateOwnersTopDown()
或类似之前em.merge(node)
(通常在一个事务中)- 但我必须把它添加到每一个EJB /交易方法
我不知道是否有一些巧妙的方式来完成这一点。
我不是数据库专家,但它可以实现与存储过程/触发器/任何东西的一致性?
如果为true,是否可以/合法地调用程序/触发器/ @PrePersist
/中的任何内容?
我在EclipseLink 2.5.2和MySQL 5.6上
谢谢。
答
我实现我自己的监听器子系统:
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;
}
的EclipseLink 2.5.2具有JPA 2.1。 – Tiny 2014-09-27 10:56:57
你说得对。谢谢。 – 2014-09-27 10:57:43