10

I have a Spring boot 1.4.2 application with Hibernate 5.2.6 and Spring data Envers 1.0.5. I am auditing my entities and the audit records are persisted properly.

My application config class is annotated to use the EnversRevisionRepositoryFactoryBean.class as the JPA repository factory.

Application config

@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
@EnableTransactionManagement
public class ApplicationConfig {}

I am trying to read the revisions for an audited entity. The entity repository extends RevisionRepository.

Entity Models

@Entity(name = "Base")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.INTEGER)
@Table(name = "BASE")
@Audited
public abstract class Base {

  @Id
  @GeneratedValue(generator = "baseSeq", strategy = GenerationType.SEQUENCE)
  @SequenceGenerator(name = "baseSeq", sequenceName = "BASE_SEQ", allocationSize = 1)
  @Column(name = "id", updatable = false, nullable = false)
  private Long id;

  @Column(name = "name", nullable = false)
  private String name;

  @Column(name = "name", nullable = false)
  private long barId;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public long getBarId() {
    return barId;
  }

  public void setBarId(long barId) {
    this.barId = barId;
  }

  public abstract String getType();

}

@Entity
@DiscriminatorValue("1")
@Audited
@NamedQueries({
    @NamedQuery(
        name = "Foo.findById",
        query = "select f from Base b where b.id = ?1"),
    @NamedQuery(
        name = "Foo.findByBarId",
        query = "select f from Base b where b.barId = ?1")})
public class Foo extends Base {
    private String type = "Foo";

    @Override
    public String getType() {
      return type;
    }
}

Entity repository

interface FooRepository extends JpaRepository<Foo, Long>,
    JpaSpecificationExecutor<Foo>, RevisionRepository<Foo, Long, Integer> {

  foo findById(Long Id);

  foo findByBarId(Long barId);

}

The application start up fails as the repository cannot be initialized due to a PropertyReferenceException.

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property findRevisions found for type Foo! at org.springframework.data.mapping.PropertyPath.(PropertyPath.java:77) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243) at org.springframework.data.repository.query.parser.Part.(Part.java:76) at org.springframework.data.repository.query.parser.PartTree$OrPart.(PartTree.java:235) at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373) at org.springframework.data.repository.query.parser.PartTree$Predicate.(PartTree.java:353) at org.springframework.data.repository.query.parser.PartTree.(PartTree.java:84) at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.(PartTreeJpaQuery.java:63) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:214) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:77) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.(RepositoryFactorySupport.java:435) at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:220) at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:266) at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:252) at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)

From what I understand, this should work out of the box. It seems like the repository is being bound to a different implementation than the desired one. Any ideas?

Relevant snippets from the gradle build script

buildscript {
    ext {
        springBootVersion = "1.4.2.RELEASE"
        verifier_version = "1.0.0.RELEASE"
    }
    repositories {
        maven {url "https://plugins.gradle.org/m2/"}
        maven {url "http://repo.spring.io/plugins-release"}
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7") // this enables optional dependencies
        classpath("io.spring.gradle:dependency-management-plugin:0.6.1.RELEASE")
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("se.transmode.gradle:gradle-docker:1.2")
        classpath("com.commercehub:gradle-cucumber-jvm-plugin:0.7")
        classpath("org.ajoberstar:grgit:1.1.0")
        classpath("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.1-rc3")
        classpath("gradle.plugin.org.detoeuf:swagger-codegen-plugin:1.6.3")
        classpath("org.springframework.cloud:spring-cloud-contract-gradle-plugin:${verifier_version}")
        classpath "net.linguica.gradle:maven-settings-plugin:0.5"
    }
}
...
dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Brixton.SR7"
        mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${verifier_version}"
        mavenBom 'org.springframework.cloud:spring-cloud-stream-dependencies:Brooklyn.SR1'
    }
}
...
compile(
        "org.springframework.boot:spring-boot-starter-data-jpa",
        'org.springframework.data:spring-data-commons',       
        'org.springframework.cloud:spring-cloud-starter-config',
        'org.springframework.cloud:spring-cloud-starter-eureka',
        'org.springframework.cloud:spring-cloud-starter-sleuth',
        'org.springframework.cloud:spring-cloud-sleuth-zipkin', 
        'com.netflix.hystrix:hystrix-javanica',                 
        'org.springframework.boot:spring-boot-starter-aop',     
        "org.springframework.boot:spring-boot-starter-web",
        "io.swagger:swagger-annotations:1.5.9",
        "com.google.code.gson:gson:2.7",
        "gradle.plugin.org.detoeuf:swagger-codegen-plugin:1.6.3",
        "org.springframework:spring-orm",
        "com.oracle.jdbc:ojdbc7:12.1.0.2",
        'org.springframework.cloud:spring-cloud-stream',
        'org.springframework.cloud:spring-cloud-stream-test-support',
        'org.springframework.cloud:spring-cloud-stream-binder-test',
        "org.springframework.boot:spring-boot-starter-hateoas",
        "com.fasterxml.jackson.module:jackson-module-parameter-names",
        "com.fasterxml.jackson.datatype:jackson-datatype-jdk8",
        "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.1",
        "org.hibernate:hibernate-core:5.2.6.Final",
        "org.hibernate:hibernate-envers:5.2.6.Final",
        "org.springframework.data:spring-data-envers:1.0.6.RELEASE"
)

Thanks in advance.

8
  • Can include your Foo entity model please? Commented Jan 4, 2017 at 17:12
  • @Naros, I have edited my post to add the entity model. It seems like Spring is interpreting the RevisionRepository methods to be auto generated query candidates for entity properties instead of binding the interface implementation methods? Commented Jan 4, 2017 at 17:48
  • Can you confirm that you have version 5.2.6.Final of the hibernate-envers artifact on the classpath and not an older one? Commented Jan 4, 2017 at 18:40
  • Yes. You set me straight on that a couple of weeks ago :) Commented Jan 4, 2017 at 18:47
  • Have you tried not overriding the versions of Hibernate and Envers used and let it use the default versions to see if it works? Perhaps there is a compatibility issue but this afaict looks to be some type of spring-data or spring-data-envers issue. Commented Jan 4, 2017 at 19:04

2 Answers 2

26

You need to add an attribute @EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class) to your application class (the class annotated with @SpringBootApplication)

As shown in this answer: https://stackoverflow.com/a/36416266

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, but if you see my original post, I already have that annotation. Did not help.
Find and remove the annotation @EnableJparepositories not in your application class.
0

You can replace @EnableJpaRepositories with @EnableEnversRepositories and it will work as needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.