【问题标题】:Dynamically creating spring EnversRevisionRepository from a Java Class从 Java 类动态创建 spring EnversRevisionRepository
【发布时间】:2021-05-02 12:39:38
【问题描述】:

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

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

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

}

【问题讨论】:

  • 编写自定义注释处理器。
  • 可能需要比这更多的细节。这个问题的重点是根本不需要创建接口定义,所以我不确定自定义注释处理器将如何提供帮助。

标签: java spring-data audit revision spring-data-envers


【解决方案1】:

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)
  • 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
  )
;

【讨论】:

  • 太棒了,谢谢,还没有尝试过,但很快就会需要它,所以非常感谢您的宝贵时间。
  • 欢迎您@GrowlingBadger。我希望它有所帮助。请,如果您对代码有任何问题,请告诉我,我很乐意根据需要对其进行调整,以便为您提供适当的解决方案。
猜你喜欢
  • 1970-01-01
  • 2011-04-05
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2014-02-27
  • 2011-10-30
  • 1970-01-01
相关资源
最近更新 更多