我有2个Maven项目在他们各自的POM中共享一个JPA项目作为依赖项。JPA项目在2.1版上,并且成功实现了hibernateenvers。但是,我现在需要创建一个自定义的RevisionEntity,因为我需要审核其他属性,例如登录的用户ID。问题是:
一世。我不能在JPA项目中直接实现
ii。父maven项目的检索登录用户的实现不同。
真正的挑战实际上是实现RevisionListener。我尝试在JPA项目本身中创建一个抽象类的修订侦听器,可以在每个父Maven项目中扩展和实现它。大声笑!这没用!
无论如何,我将不胜感激。有出路吗?
我不能在JPA项目中直接实现
如果 信息 不管使用JPA的应用程序这两个应用程序的要收集有关每个版本是相同的,那么就应该在落实共同JPA项目的修订实体和监听功能没有问题。您无法执行此操作的唯一原因是,如果 信息 (即 表结构) 不同。
为此,我们需要一个抽象层。而不是RevisionListener像尝试那样扩展,您将拥有另一个接口,该接口代表侦听器将需要的 服务 ,然后在子项目中实现该服务。
RevisionListener
/** * Interface that implementations should extend to provider revision * information to the Envers revision listener. */ public interface RevisionInfoProvider { String getUserName(); } /** * A class that holds a RevisionInfoProvider as a ThreadLocal. */ public class RevisionInfoProviderHolder { public static RevisionInfoProvider getProvider() { // impl details here to get a RevisionInfoProvider. } }
然后,您的修订版侦听器实现可能类似于以下内容:
public class RevisionListenerImpl implements RevisionListener { @Override public void newRevision(Object revisionEntity) { if ( CustomRevisionEntity.class.isInstance( revisionEntity ) ) { CustomRevisionEntity entity = (CustomRevisionEntity) revisionEntity; // get provider from thread local and set user details RevisionInfoProvider provider = RevisionInfoProviderHolder.getProvider(); entity.setUserName( provider.getUserName() ); } // todo: may want to assert in case you change entity types? } }
此时,只需CustomRevisionEntity正确创建您的,并对其进行批注,包括将其指向RevisionListenerImplEnvers应该使用的侦听器实现所指向的类。
CustomRevisionEntity
RevisionListenerImpl
现在,在每个子项目中,您需要做的就是:
第一个只是JPA项目如何从每个子项目获取详细信息的网关。例如,在spring Web应用程序中,这可能只是一些spring服务bean。
第二个只是每个线程在调用任何JPA东西之前需要做的事情。同样在Spring Web应用程序中,这可能是某种类型的Web过滤器,该过滤器在调用用户代码以确保正确设置ThreadLocal之前在过滤器链的顶部执行。
父maven项目的检索登录用户的实现不同。
回到上面,正如您在上面看到的那样,带有RevisionInfoProvider句柄的抽象层可以很好地处理此问题。您为Envers建立了一个通用框架,以使其发挥作用,同时又使其具有足够的灵活性,以便每个父项目可以根据需要进行区分。
RevisionInfoProvider
如果您确实遇到这种情况,则需要在每个父项目中分别实现修订实体和侦听器, 或者 遵循我上面提到的内容,但使用满足 两个 父模块要求的修订实体。
您只需要确保在检查实体的引导阶段期间可以通过JPA模块选择修订实体。
希望这可以帮助。