2

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.

Minimal reproductible exemple

asked Sep 1, 2019 at 0:11

1 Answer 1

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.

answered Sep 1, 2019 at 7:50
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your help, however after modifying my code to fit yours doesn't solve my problem. Would you have a working exemple ?
you can refer this github.com/iamitpatil1993/spring-data-jpa/commit/… Names are quite different, hope this help.
Thanks for your efforts, however I think that my issue is that I don't use the same version of spring-data-jpa. Here is a minial exemple : github.com/ptitFicus/spring-data-jpa-generic-custom-repository
As I noticed this problem occurs only when repo is generic.. Did you solve this problem?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.