Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EnversRevisionRepositoryFactoryBean doesn't use custom RevisionEntity #4

Closed
raoulk opened this issue Sep 28, 2012 · 7 comments
Closed
Milestone

Comments

@raoulk
Copy link

raoulk commented Sep 28, 2012

I use a custom RevisionEntity with @RevisionNumber of type Long (instead of Integer).
The creation of my repository

public interface CustomerRepository extends RevisionRepository<Customer, UUID, Long>

fails:

java.lang.IllegalStateException: Configured a revision entity type of interface com.test.CustomerRepository with a revision type of class java.lang.Integer but the repository interface is typed to a revision type of class java.lang.Long!

in line 121 of the EnversRevisionRepositoryFactoryBean. Debugging showed me that the revisionEntityInformation attribute contains a DefaultRevisionEntityInformation object. I would expect a ReflectionRevisionEntityInformation object that contains information about my custom RevisionEntity. My RevisionEntity looks like this:

@Entity
@RevisionEntity
@SequenceGenerator(name = "REVISION_SEQ", sequenceName = "revision_seq")
public class RevEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "REVISION_SEQ")
    @RevisionNumber
    public Long id;

    @RevisionTimestamp
    public Long timestamp;

    @Transient
    public Date getRevisionDate() {
        return new Date(getTimestamp());
    }

    public Long getId() {
        return id;
    }

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

    public Long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Long timestamp) {
        this.timestamp = timestamp;
    }
}
@odrotbohm
Copy link
Member

The EnversRepositoryFactoryBean already exposes a property to customize the revision entity class. If this property is set the ReflectionRevisionEntityInformation information will be used. So the problem currently is that the infrastructure does not know about your special RevEntity class, and the namespace configuration you probably use does not expose the property. You should be able to workaround the issue by extending EnversRepositoryFactoryBean as follows:

public class CustomEnversRevisionRepositoryFactoryBean extends EnversRevisionRepositoryFactoryBean {
  public FooCustomEnversRevisionRepositoryFactoryBean() {
    setRevisionEntityClass(RevEntity.class);
  }
}

then you can alter your Spring Data JPA config as follows:

<jpa:repositories base-package="" factory-class="….CustomEnversRevisionRepositoryFactoryBean" />

We'll probably add a custom <envers:repositories /> element to the Spring Data Envers project that will expose the revision entity class attribute directly to ease the setup.

@raoulk
Copy link
Author

raoulk commented Sep 28, 2012

Thnx, extending is a good idea.
I was already wondering how to use the setRevisionEntityClass()-Method in the EnversRepositoryFactoryBean, as it is not used as a plain bean ref but as a factory-class....

@raoulk raoulk closed this as completed Sep 28, 2012
@dk2k
Copy link

dk2k commented Sep 26, 2018

public class CustomEnversRevisionRepositoryFactoryBean extends EnversRevisionRepositoryFactoryBean { public FooCustomEnversRevisionRepositoryFactoryBean() { setRevisionEntityClass(RevEntity.class); } }

In the version of hibernate-envers 5.1.1.Final and spring-data-envers 1.1.15.RELEASE this code doesn't work since EnversRevisionRepositoryFactoryBean has no default constructor (and keeping in mind that "Foo" in constructor name is a typo).
This code worked for me:

public class CustomEnversRevisionRepositoryFactoryBean extends EnversRevisionRepositoryFactoryBean {
    public CustomEnversRevisionRepositoryFactoryBean(Class repositoryInterface) {
        super(repositoryInterface);
        setRevisionEntityClass(AbonRevision.class);
    }
}

@scordio
Copy link
Contributor

scordio commented Mar 26, 2021

We'll probably add a custom <envers:repositories /> element to the Spring Data Envers project that will expose the revision entity class attribute directly to ease the setup.

Hi @odrotbohm, I couldn't find anything about it so I guess this was never added. Is it something you would still consider or is subclassing the preferred approach?

@odrotbohm
Copy link
Member

We have no plans to extend our XML based configurations at the moment.

@scordio
Copy link
Contributor

scordio commented Mar 26, 2021

Thanks for the fast feedback!

What about something for Java config? I could imagine a custom annotation to avoid the EnversRevisionRepositoryFactoryBean custom class wired into @EnableJpaRepositories.

I'm happy to contribute if the idea is acceptable.

@odrotbohm
Copy link
Member

We just created #289.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants