spring-data-envers icon indicating copy to clipboard operation
spring-data-envers copied to clipboard

spring data envers doesn't support custom queries.

Open ratheemohan opened this issue 6 years ago • 2 comments

Hi,

I have TestEntity backed by table name TEST as shown below and have enabled spring data envers. The audit table is called TEST_AUD. I am trying to write a custom query to fetch the Revisions based on userId, but couldn't find a way to do it. please could someone help with this?

@Entity
@Table(name = "TEST")
public class TestEntity {
       @Id
       private long id;

      @Column("USER_ID")
      private long userId;
 
}

Thanks

ratheemohan avatar Apr 24 '18 09:04 ratheemohan

Related StackOverflow question https://stackoverflow.com/q/36008394/66686

schauder avatar Dec 18 '18 08:12 schauder

Spring Data Envers in fact does support custom methods in exactly the way it is described in the documentation: https://docs.spring.io/spring-data/envers/docs/current/reference/html/#repositories.custom-implementations

What is not supported are @Query annotations or query derivation where a query is derived from the method name. The first doesn't seem to be feasible since there doesn't seem to be a query language for querying revisions. The second would need someone to come up with reasonable semantics that doesn't interfere with the semantics of the query derivation of the main repository. I seriously doubt this is worth the effort since the number of ways one might want to query revisions is pretty huge and we would always only be able to support a slim slice via query derivation.

If anybody has a suggestion for reasonable semantics a comment describing it would be most welcome.

A custom implementation might look like this:

public class CustomCountryRepositoryImpl implements CustomCountryRepository {

	@Autowired
	EntityManager entityManager;

	@Override
	public List<Country> findByDate(Date revisionDate) {

		AuditReader auditReader = AuditReaderFactory.get(entityManager);

		Number revision = auditReader.getRevisionNumberForDate(revisionDate);

		return auditReader //
				.createQuery() //
				.forEntitiesAtRevision(Country.class, revision) //
				.getResultList();

	}
}

The interfaces to go with that would look like:

@Transactional
public interface CustomCountryRepository {
	List<Country> findByDate(Date revisionDate);
}

and

public interface CountryRepository
		extends RevisionRepository<Country, Long, Integer>, JpaRepository<Country, Long>, CustomCountryRepository {

}

schauder avatar Dec 18 '18 09:12 schauder