Using spring data, I have two tables that shares the same structure. The two tables are represented by two different entities, that inherit from the same class :
@MappedSuperclass
public abstract class SuperEntity<T extends SuperEntity> {
// ...
}
@Table(name = "FOO")
@Entity
public class Foo extends SuperEntity<Foo> {
// ...
}
@Table(name = "BAR")
@Entity
public class Bar extends SuperEntity<Bar> {
// ...
}
I also have a generic repository, that I would like to use to factorize to requesting logic, and two sub-repository : one for each table.
public interface GenericEvtRepository <T extends SuperEntity<?>> extends JpaRepository<T, String> { }
public interface FooRepository extends GenericEvtRepository<Foo> {}
public interface BarRepository extends GenericEvtRepository<Bar> {}
I would like to add an actual query implementation to this repository (i.e. using EntityManager / Criteria). Therefore I tried to adapt the custom repository strategy to my generic case
@Repository
public class GenericEvtRepositoryImpl<T extends SuperEntity<?>> extends SimpleJpaRepository<T, String> implements GenericEvtRepository<T> {
@PersistenceContext
EntityManager entityManager;
// Some logic using entityManager
public SuperEntity myCustomRequest() { /*...*/ }
}
However my application doesn't start, with the exception :
org.springframework.data.mapping.PropertyReferenceException: No property myCustomRequest found for type Foo!
Not sure what I'm doing wrong, but Spring seems to think that myCustomRequest is an attribute from my entities, instead of a method.
I'm using spring-boot 1.5.6 and spring-data-jpa 1.11.6.
1 Answer 1
Luckily I was able to reproduce your issue,
How spring recommends custom repository implementation is specified here in spring docs.
So, you can do something like below,
public interface CustomEntityRepository<T extends SuperTag<?>>
public interface FooRepository extends JpaRepository<Foo, Integer>, CustomEntityRepository<Foo>
public interface BarRepository extends JpaRepository<Bar, Integer>, CustomEntityRepository<Bar>
And define common implementation for CustomEntityRepository<T extends SuperTag<?>> as below,
@Repository
// NOTE: Implementation name must follow convension as InterfaceName + 'Impl'
public class CustomEntityRepositoryImpl<T extends SuperTag<?>> implements
CustomEntityRepository<T> {
@PersistenceContext
private EntityManager entityManager;
// Generic custom implementation here
}
Spring automatically detects implementation of Custom Interface CustomEntityRepository based on implementation class naming convention.
4 Comments
Explore related questions
See similar questions with these tags.