从 Java 类动态创建 spring EnversRevisionRepository

问题描述

如何在给定 Java Class 对象的情况下动态创建 EnversRevisionRepository

感谢这个答案 https://stackoverflow.com/a/22342025/3771679一个人可以成功地动态创建一个 JpaRepository,但我想为一个等效于的存储库实现相同的目标:

public interface MyRevisionedRepository extends RevisionRepository<X,Y,Z>,JpaRepository<X,Y> {

}

解决方法

Spring Data 提供 EnversRevisionRepositoryImpl 作为默认的 RevisionRepository 实现。

正如您在存储库构造函数中看到的:

    /**
     * Creates a new {@link EnversRevisionRepositoryImpl} using the given {@link JpaEntityInformation},* {@link RevisionEntityInformation} and {@link EntityManager}.
     *
     * @param entityInformation must not be {@literal null}.
     * @param revisionEntityInformation must not be {@literal null}.
     * @param entityManager must not be {@literal null}.
     */
    public EnversRevisionRepositoryImpl(JpaEntityInformation<T,?> entityInformation,RevisionEntityInformation revisionEntityInformation,EntityManager entityManager) {

        Assert.notNull(revisionEntityInformation,"RevisionEntityInformation must not be null!");

        this.entityInformation = entityInformation;
        this.entityManager = entityManager;
    }

您需要三件事来创建该存储库的新实例:

  • 一个 EntityManager,您可以使用 @PersistenceContext 或可能(我从未测试过)通过 @Autowiring 轻松获得。

  • JpaEntityInformation。遵循 SimpleJpaRepository 的示例:

final JpaEntityInformation<T,?> entityInformation =
  JpaEntityInformationSupport.getEntityInformation(domainClass,em)
  • A RevisionEntityInformation。奇怪的是,因为对象被断言不为空,但实际上它在其余的实现代码中似乎没有使用。在这里,我们可以按照EnversRevisionRepositoryFactoryBean的例子:
final RevisionEntityInformation revisionEntityInformation =
  Optional.ofNullable(revisionEntityClass) //
    .filter(it -> !it.equals(DefaultRevisionEntity.class))//
    .<RevisionEntityInformation> map(ReflectionRevisionEntityInformation::new) //
    .orElseGet(DefaultRevisionEntityInformation::new); 

DefaultRevisionEntityInformation 是包范围的,但您可以轻松重现它:

import org.hibernate.envers.DefaultRevisionEntity;
import org.springframework.data.repository.history.support.RevisionEntityInformation;

/**
 * {@link RevisionEntityInformation} for {@link DefaultRevisionEntity}.
 */
public class DefaultRevisionEntityInformation implements RevisionEntityInformation {

    /*
     * (non-Javadoc)
     * @see org.springframework.data.repository.history.support.RevisionEntityInformation#getRevisionNumberType()
     */
    public Class<?> getRevisionNumberType() {
        return Integer.class;
    }

    /*
     * (non-Javadoc)
     * @see org.springframework.data.repository.history.support.RevisionEntityInformation#isDefaultRevisionEntity()
     */
    public boolean isDefaultRevisionEntity() {
        return true;
    }

    /*
     * (non-Javadoc)
     * @see org.springframework.data.repository.history.support.RevisionEntityInformation#getRevisionEntityClass()
     */
    public Class<?> getRevisionEntityClass() {
        return DefaultRevisionEntity.class;
    }
}

总结:

// Obtain a reference to the underlying EntityManager
final EntityManager entityManager = ...;
// Provide JpaEntityInformation
final JpaEntityInformation<User,?> entityInformation =
  JpaEntityInformationSupport.getEntityInformation(User.class,entityManager);
// Provide RevisionEntityInformation. The solution is based on 
// DefaultRevisionEntity but you can provide your custom revision entity
// if appropriate
final RevisionEntityInformation revisionEntityInformation =
  new DefaultRevisionEntityInformation();
// Build your custom revision repository,for example:
final RevisionRepository userRevisionRepository =
  new EnversRevisionRepositoryImpl<User,Integer,DefaultRevisionEntity>(
    entityInformation,revisionEntityInformation,entityManager
  )
;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...