我有
@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);
}
}
}
即使我知道它不合法,事实上,这些不起作用(@PreUpdate
仅在根目录上调用。)
我知道我可以
addOwner()
方法,将所有者传播给子级
node.getOwnerList().add(owner)
传播被破坏或
propagateOwnersTopDown()
或类似em.merge(node)
之前的内容(通常在事务内部)
我想知道是否有一些巧妙的方法来实现这一目标。
我没有数据库专家,但是可以实现与存储过程/触发器/任何内容的一致性吗?
如果为true,是否可以/合法地调用@PrePersist
/ @PreUpdate
中的过程/触发器/任何内容?
我在EclipseLink 2.5.2和MySQL 5.6上
谢谢。
答案 0 :(得分:0)
我实现了自己的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;
}