My UserRepository:
public interface UserRepository extends CrudRepository<User, Integer> {
List<User> findAll(List<Integer> ids);
}
Error:
Caused by:
org.springframework.data.mapping.PropertyReferenceException: No
property findAll found for type User
Refer - http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html?is-external=true#findAll-java.lang.Iterable-
Can some one tell me how to get list of User objects based on List of Id's.
This is working
#Query(" select new User(id,x,y,z) from User b where b.id in ?1 ")
List<User> findById(List<Integer> id);
Firstly, I would rename the repository to UserRepository, because having 2 User classes is confusing.
findAll(), by definition, is meant to get all the models with no criteria. You should add a method named
findByIdIn(Collection<Integer> ids)
Use List<User> findAll(Iterable<Integer> ids) or List<User> findByIdIn(List<Integer> ids)
Related
public interface UserDao {
User getUserById(Long id);
void saveUser(User user);
List<UserDto> getAllUsers();
boolean isExistUserByEmail(String email);
boolean isExistUserByUserName(String userName);
// get users by id list
List<User> getUsersByIdIn(List<Long> idList);
// get all active users
List<UserDto> getAllActiveUsers();
User getUserByEmail(String email);
void saveAllUsers(List<User> userList);
List<Object[]> getAllInstructors();
}
This my dao impl method
#Override
public List<Object[]> getAllInstructors() {
return userRepository.getAllInstructors();
}
This is the query from my repository layer
#Query(value = "select distinct u.first_name, u.last_name, u.full_name, u.id from public.user u inner join public.users_group ug on u.id = ug.user_id and ug.group_list_id=1 WHERE status=1 ORDER BY u.id DESC", nativeQuery = true)
This is the method in my controller layer
#GetMapping("/instructors")
public List<Object[]> getAllIntsructors() {
return userService.getAllInstructors();
}
Result when I call the api on postman
The result I expect is:
first_name: "Iresha"
second_name: "Vishwakala"
But I don't get the key. I only get an array of objects showing me the values.
The way you are using your Repo is not a good practice. To be honest I have never seen it before.
This would be the correct way to do it:
public interface UserRepository extends JpaRepository<UserEntity, Long> // Here the first is the Entity which will be fetched by this repo, and the second is the type of ID that this Entity has.
{
// I am supposing that your entity is UserEntity and has an ID of type Long.
// Here come the queries which must return primitives or UserEntity (list, set etc.)
// An example query would be:
#Query(value = "....", nativeQuery = true) List<UserEntity> getUsersAsYouWant();
}
The JpaRepository makes use of Java Generics (hence the <>), that is why you must supply the class the types that it has to map the DB rows/data to. If you want to return specific types/Dtos/List you may use the same Repo but with different Query building (not native but JPQL). But that would be yet another question. If you want to check more, see my answer here.
Is there a way to return Iterable< IUser > where IUser is a projection of User entity.
Example<User> userExample = Example.of(user, userMatcher);
Iterable<User> foundUsers = userRepository.findAll(userExample, Sort.by("createdAt").descending());
Instead of sticking with spring data auto generated query and response type.
You can create your own HQL query by using #Query annotation so that you can except your custom return type.
Example :
#Query(" select user from User as user where user.userName like %:username% order by createdAt desc")
public List<User> findAllByUserName(String username);
I have a PostgreSQL table where channel_ids field is BIGINT[].
In console I can search like so:
select * FROM user where 10000=ANY(channel_ids).
But I can't figure out how to build up the Specification for search in JpaRepository.
public interface UserRepository extends JpaRepository<User, Long> {
Page<User> findAll(Specification<User> spec, Pageable pageable);
}
Is it even supported?
I have a JpaRepository:
public interface UserRepository extends JpaRepository<User, Long> {
List<User> getByFirstName(String firstName);
}
But how to search in several values? I need something like this:
List<User> getByFirstNames(List<String> firstNames);
You need to change the signature of the method to:
List<User> getByFirstNameIn(List<String> firstNames);
Take a look at all the supported method of Spring Data JPA on their reference.
The following code is working,
Code in Repository,
List<Shop> findByNameIn(List<String> names);
Code in controller,
List<String> names=new ArrayList<String>();
names.add("gunaa");
names.add("pranav");
List<Shop> sl=shopService.findByNameIn(names);
for(Shop s:sl)
System.out.println(s.getName());
I want to make use of a #NamedQuery inside a JpaRepository. But it does not work:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
#Query(name = MyEntity.FIND_ALL_CUSTOM)
List<MyEntity> findAllCustom(Pageable pageable);
}
#Entity
#NamedQuery(
name = MyEntity.FIND_ALL_CUSTOM, query = "select * from MyEntity me where me.age >= 18"
)
public class MyEntity {
public static final String FIND_ALL_CUSTOM = "findAllCustom";
}
Result:
org.springframework.data.mapping.PropertyReferenceException: No property findAllCustom found for type MyEntity!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235)
at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:84)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:61)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:94)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:205)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:72)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:369)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:192)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
... 28 more
Update:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
List<MyEntity> findAllCustom(Pageable pageable);
}
#Entity
#NamedQuery(
name = "MyEntity.findAllCustom", query = "select * from MyEntity me where me.age >= 18"
)
public class MyEntity {
}
Still same exception:
PropertyReferenceException: No property findAllCustom found for type MyEntity!
Take a look at the documentation of Spring Data JPA - Using JPA NamedQueries.
I advise you follow the conventions set in the documentation (starting with the simple name of the configured domain class, followed by the method name separated by a dot). Cut the underscore and name the query like
#NamedQuery(name = "MyEntity.findAllCustom", query="...")
or even better add a suggestive name like findByAge or sth.
To allow execution of these named queries all you need to do is to specify MyEntityRepository as follows:
public interface MyEntityRepository extends JpaRepository <MyEntity, Long> {
List<MyEntity> findAllCustom();
}
I implemented it with the JpaRepository as the documentation exemplifies. But you could try with a simple CrudRepository and see if that works.
I think the problem was you where using #Query and the Queries annotated to the query method will take precedence over queries defined using #NamedQuery. Read the docs for the #Query usage, i think you where also using it wrong.
Update
To use the Pageable, according to this answer
to apply pagination, a second subquery must be derived. Because the
subquery is referring to the same fields, you need to ensure that your
query uses aliases for the entities/tables it refers to
that means you would rewrite your query like
query ="select * from MyEntity me where me.age >= 18".
The example was used for #Query, but that is also a named query so it should apply to your case as well. The only difference is that with #Query you actually bind them directly rather than annotating them to the domain class.
Update 2
I tried in my own app.
First off you should have the query using the alias instead of * (i.e me).
Secondly the string you use FIND_ALL_CUSTOM is not following the convention which is "MyEntity.findAllCustom".
Solution
Copy paste this:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
List<MyEntity> findAllCustom(Pageable pageable);
List<MyEntity> findAllCustom();
}
#Entity
#NamedQuery(
name = MyEntity.FIND_ALL_CUSTOM, query = "select me from MyEntity me where me.age >= 18"
)
public class MyEntity {
public static final String FIND_ALL_CUSTOM = "MyEntity.findAllCustom";
}
Both will work. For the one with the pageable method argument call it as myEntityRepository.allCustom(new PageRequest(0,20)). Ofc, you know that myEntityRepository is injected.