Spring Data JPA How to build a generic Repository for multiple entities? [duplicate]
up vote
0
down vote
favorite
This question already has an answer here:
Generic Repository in Spring JPA
2 answers
I'm beginning to work with Spring Data JPA repositories. We have an application already using Spring MVC (No spring boot or spring data JPA), where we have written a Generic DAO class that handles basic CRUD operations for virtually all entities that we have. Any other special operations can be handled by writing custom DAOs.
Now, Spring data JPA has made things very easy by requiring us to write only an interface and the rest is taken care of.
public interface PersonRepository extends JpaRepository<Person, Long> {
}
This is cool, but I was wondering if I can introduce generics here.
The reason is, my application has a number of entities for which we need to perform only basic CRUD operations and nothing more. Which means, for every entity, we need to write an interface. Though the code is minimal, it results in one file for each entity, which I guess can be avoided (true?).
My question is, can I write a generic Repository class like
public interface GenericRepository<T> extends JpaRepository<T, Long> {
}
so that my service class can look like this
@Autowired
private GenericRepository<Person> personRepository;
public List<Person> findAll() {
return this.personRepository.findAll();
}
This will be a much cleaner approach for basic operations, as one Repository interface handles a number of entities.
EDIT
It turns out that I can indeed create a repository interface as I illustrated above, but when the application starts, I get an error which says
Error creating bean with name 'genericRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object
This is probably because of the Generic Type
I have to say that my entities are separate classes in themselves and do not implement or extend a super entity/entities. Would it help if they did?
Please guide me in the right direction.
Thanks!
java generics spring-data-jpa
marked as duplicate by Jens Schauder
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 8 at 15:03
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
up vote
0
down vote
favorite
This question already has an answer here:
Generic Repository in Spring JPA
2 answers
I'm beginning to work with Spring Data JPA repositories. We have an application already using Spring MVC (No spring boot or spring data JPA), where we have written a Generic DAO class that handles basic CRUD operations for virtually all entities that we have. Any other special operations can be handled by writing custom DAOs.
Now, Spring data JPA has made things very easy by requiring us to write only an interface and the rest is taken care of.
public interface PersonRepository extends JpaRepository<Person, Long> {
}
This is cool, but I was wondering if I can introduce generics here.
The reason is, my application has a number of entities for which we need to perform only basic CRUD operations and nothing more. Which means, for every entity, we need to write an interface. Though the code is minimal, it results in one file for each entity, which I guess can be avoided (true?).
My question is, can I write a generic Repository class like
public interface GenericRepository<T> extends JpaRepository<T, Long> {
}
so that my service class can look like this
@Autowired
private GenericRepository<Person> personRepository;
public List<Person> findAll() {
return this.personRepository.findAll();
}
This will be a much cleaner approach for basic operations, as one Repository interface handles a number of entities.
EDIT
It turns out that I can indeed create a repository interface as I illustrated above, but when the application starts, I get an error which says
Error creating bean with name 'genericRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object
This is probably because of the Generic Type
I have to say that my entities are separate classes in themselves and do not implement or extend a super entity/entities. Would it help if they did?
Please guide me in the right direction.
Thanks!
java generics spring-data-jpa
marked as duplicate by Jens Schauder
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 8 at 15:03
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
what about stackoverflow.com/questions/23812458/… ?
– Pijotrek
Nov 8 at 14:15
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
This question already has an answer here:
Generic Repository in Spring JPA
2 answers
I'm beginning to work with Spring Data JPA repositories. We have an application already using Spring MVC (No spring boot or spring data JPA), where we have written a Generic DAO class that handles basic CRUD operations for virtually all entities that we have. Any other special operations can be handled by writing custom DAOs.
Now, Spring data JPA has made things very easy by requiring us to write only an interface and the rest is taken care of.
public interface PersonRepository extends JpaRepository<Person, Long> {
}
This is cool, but I was wondering if I can introduce generics here.
The reason is, my application has a number of entities for which we need to perform only basic CRUD operations and nothing more. Which means, for every entity, we need to write an interface. Though the code is minimal, it results in one file for each entity, which I guess can be avoided (true?).
My question is, can I write a generic Repository class like
public interface GenericRepository<T> extends JpaRepository<T, Long> {
}
so that my service class can look like this
@Autowired
private GenericRepository<Person> personRepository;
public List<Person> findAll() {
return this.personRepository.findAll();
}
This will be a much cleaner approach for basic operations, as one Repository interface handles a number of entities.
EDIT
It turns out that I can indeed create a repository interface as I illustrated above, but when the application starts, I get an error which says
Error creating bean with name 'genericRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object
This is probably because of the Generic Type
I have to say that my entities are separate classes in themselves and do not implement or extend a super entity/entities. Would it help if they did?
Please guide me in the right direction.
Thanks!
java generics spring-data-jpa
This question already has an answer here:
Generic Repository in Spring JPA
2 answers
I'm beginning to work with Spring Data JPA repositories. We have an application already using Spring MVC (No spring boot or spring data JPA), where we have written a Generic DAO class that handles basic CRUD operations for virtually all entities that we have. Any other special operations can be handled by writing custom DAOs.
Now, Spring data JPA has made things very easy by requiring us to write only an interface and the rest is taken care of.
public interface PersonRepository extends JpaRepository<Person, Long> {
}
This is cool, but I was wondering if I can introduce generics here.
The reason is, my application has a number of entities for which we need to perform only basic CRUD operations and nothing more. Which means, for every entity, we need to write an interface. Though the code is minimal, it results in one file for each entity, which I guess can be avoided (true?).
My question is, can I write a generic Repository class like
public interface GenericRepository<T> extends JpaRepository<T, Long> {
}
so that my service class can look like this
@Autowired
private GenericRepository<Person> personRepository;
public List<Person> findAll() {
return this.personRepository.findAll();
}
This will be a much cleaner approach for basic operations, as one Repository interface handles a number of entities.
EDIT
It turns out that I can indeed create a repository interface as I illustrated above, but when the application starts, I get an error which says
Error creating bean with name 'genericRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object
This is probably because of the Generic Type
I have to say that my entities are separate classes in themselves and do not implement or extend a super entity/entities. Would it help if they did?
Please guide me in the right direction.
Thanks!
This question already has an answer here:
Generic Repository in Spring JPA
2 answers
java generics spring-data-jpa
java generics spring-data-jpa
asked Nov 8 at 14:04
sriramsridharan
180417
180417
marked as duplicate by Jens Schauder
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 8 at 15:03
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Jens Schauder
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 8 at 15:03
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
what about stackoverflow.com/questions/23812458/… ?
– Pijotrek
Nov 8 at 14:15
add a comment |
what about stackoverflow.com/questions/23812458/… ?
– Pijotrek
Nov 8 at 14:15
what about stackoverflow.com/questions/23812458/… ?
– Pijotrek
Nov 8 at 14:15
what about stackoverflow.com/questions/23812458/… ?
– Pijotrek
Nov 8 at 14:15
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
I think you could do it like this:
@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
//added custom common functionality for all the GenericRepository implementations
public List<T> findByAttributeContainsText(String attributeName, String text);
}
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements GenericRepository<T, ID> {
private EntityManager entityManager;
public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Transactional
public List<T> findByAttributeContainsText(String attributeName, String text) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> cQuery = builder.createQuery(getDomainClass());
Root<T> root = cQuery.from(getDomainClass());
cQuery.select(root).where(builder.like(root.<String>get(attributeName), "%" + text + "%"));
TypedQuery<T> query = entityManager.createQuery(cQuery);
return query.getResultList();
}
}
public interface MyOtherRepository extends GenericRepository<Role, Long> {
}
And in your config class:
@Configuration
@EnableJpaRepositories(basePackages="com.myProject", repositoryBaseClass =
GenericRepositoryImpl.class)
public class JpaConfig {
}
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
I think you could do it like this:
@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
//added custom common functionality for all the GenericRepository implementations
public List<T> findByAttributeContainsText(String attributeName, String text);
}
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements GenericRepository<T, ID> {
private EntityManager entityManager;
public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Transactional
public List<T> findByAttributeContainsText(String attributeName, String text) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> cQuery = builder.createQuery(getDomainClass());
Root<T> root = cQuery.from(getDomainClass());
cQuery.select(root).where(builder.like(root.<String>get(attributeName), "%" + text + "%"));
TypedQuery<T> query = entityManager.createQuery(cQuery);
return query.getResultList();
}
}
public interface MyOtherRepository extends GenericRepository<Role, Long> {
}
And in your config class:
@Configuration
@EnableJpaRepositories(basePackages="com.myProject", repositoryBaseClass =
GenericRepositoryImpl.class)
public class JpaConfig {
}
add a comment |
up vote
0
down vote
I think you could do it like this:
@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
//added custom common functionality for all the GenericRepository implementations
public List<T> findByAttributeContainsText(String attributeName, String text);
}
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements GenericRepository<T, ID> {
private EntityManager entityManager;
public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Transactional
public List<T> findByAttributeContainsText(String attributeName, String text) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> cQuery = builder.createQuery(getDomainClass());
Root<T> root = cQuery.from(getDomainClass());
cQuery.select(root).where(builder.like(root.<String>get(attributeName), "%" + text + "%"));
TypedQuery<T> query = entityManager.createQuery(cQuery);
return query.getResultList();
}
}
public interface MyOtherRepository extends GenericRepository<Role, Long> {
}
And in your config class:
@Configuration
@EnableJpaRepositories(basePackages="com.myProject", repositoryBaseClass =
GenericRepositoryImpl.class)
public class JpaConfig {
}
add a comment |
up vote
0
down vote
up vote
0
down vote
I think you could do it like this:
@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
//added custom common functionality for all the GenericRepository implementations
public List<T> findByAttributeContainsText(String attributeName, String text);
}
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements GenericRepository<T, ID> {
private EntityManager entityManager;
public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Transactional
public List<T> findByAttributeContainsText(String attributeName, String text) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> cQuery = builder.createQuery(getDomainClass());
Root<T> root = cQuery.from(getDomainClass());
cQuery.select(root).where(builder.like(root.<String>get(attributeName), "%" + text + "%"));
TypedQuery<T> query = entityManager.createQuery(cQuery);
return query.getResultList();
}
}
public interface MyOtherRepository extends GenericRepository<Role, Long> {
}
And in your config class:
@Configuration
@EnableJpaRepositories(basePackages="com.myProject", repositoryBaseClass =
GenericRepositoryImpl.class)
public class JpaConfig {
}
I think you could do it like this:
@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
//added custom common functionality for all the GenericRepository implementations
public List<T> findByAttributeContainsText(String attributeName, String text);
}
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements GenericRepository<T, ID> {
private EntityManager entityManager;
public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Transactional
public List<T> findByAttributeContainsText(String attributeName, String text) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> cQuery = builder.createQuery(getDomainClass());
Root<T> root = cQuery.from(getDomainClass());
cQuery.select(root).where(builder.like(root.<String>get(attributeName), "%" + text + "%"));
TypedQuery<T> query = entityManager.createQuery(cQuery);
return query.getResultList();
}
}
public interface MyOtherRepository extends GenericRepository<Role, Long> {
}
And in your config class:
@Configuration
@EnableJpaRepositories(basePackages="com.myProject", repositoryBaseClass =
GenericRepositoryImpl.class)
public class JpaConfig {
}
answered Nov 8 at 14:16
SoftwareTheory
5452722
5452722
add a comment |
add a comment |
what about stackoverflow.com/questions/23812458/… ?
– Pijotrek
Nov 8 at 14:15