Spring Data Jpa #query behaviours - spring-data-jpa

Can anybody please tell me #Query annotation will support DB independence query mechanism
Example:
public interface UserRepository extends JpaRepository<User, Long> {
#Query("select u from User u where u.firstname like %?1")
List<User> findByFirstnameEndsWith(String firstname);
}
if i write this query will it support all the DBs like Mysql,oracle, postgres.
i found something like this in spring data jpa reference document site that
#Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
User findByEmailAddress(String emailAddress);
here is this means if i write nativeQuery=true it will treat as native query and if don't writer it will behave like a spring data jpa specific query or how it will behave please clarify.

If you set the nativeQuery flag to true, the query is treated as native sql whose behaviour will depend on DB host.If you dont set nativeQuery=true, then it is treated as JPQL and the real query for DB is generated by JPA according to the DB host hence it is DB independent.

Related

Spring JPA findByColumnNameLike not working

I have a method -> findByfileNameLike(fileName,1, pageable) and its declaration in a repository that extends JPA Repository is
#Query(value = QUERY)
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
#LogExecutionTime
Page<BatchDTO> findByfileNameLike(String
fileName,#Param("departmentId")Integer departmentId, Pageable pageable)
Query is Select new DTO(bdm.id.batch.status) from Table bdm where bdm.id.departmentId =:departmentId and bdm.id.batch.status <> 7";
I want to filter the query by the column fileName.I have read to give the method name as given according to the doc of spring data jpa.But its not working.
Where and how will i give the fileName to be filtered?Should it be first parameter in the method?
Once you specify a query using the annotation #Query, Spring data jpa will not automatically create a query for you based on the method name and it will rely on the query provided by using the annotation.
The method findByfileNameLike will not make any difference here as a query is provided explicitly. Hope that answers your question

Spring data jpa querydsl projection with joins

I'd like to optimize a queryDSL + Spring data query. Currently I am using a BooleanBuilder as the predicate, which would be fine, but it joins too many tables. I don't need all the columns from the tables and I don't need some of the tables at all. I believe using a projection would reduce the number of tables joined.
I tried with using a Projections.bean() and also with extending MappingProjection, but both approaches result in not using joins but selecting from multiple tables which results in less rows than what's needed.
My data structure consists of a Booking entity and some related entites like User, so looks something like the following:
#Entity
public class Booking {
#ManyToOne
#JoinColumn(name = "userId", nullable = false)
private User endUser;
}
#Entity
public class User {
#OneToMany(cascade = CascadeType.ALL, mappedBy = "endUser", fetch = FetchType.LAZY)
private List<Booking> bookings;
}
I implemented a custom queryDSL projection repository as described here: Spring Data JPA and Querydsl to fetch subset of columns using bean/constructor projection
I'm trying a projection like the following:
Projections.bean(Booking.class,
booking.uuid,
Projections.bean(User.class,
booking.endUser.uuid
).as(booking.endUser.getMetadata().getName()
);
The sql generated by the current solution looks something like this:
select (...)
from booking booking0_,
user user12_
where booking0_.user_id=user12_.id
So, how can I make QueryDSL join the tables instead of selecting from all of them?
Am I on the right path to try to optimize the query? Does the projection make sense?
I ended up creating a DB view, making an Entity for it and then querying that with querydsl. This is really simple, straightforward and the performance is good too.
This is probably where ORMs are just not capable enough.

Spring Data JPA - Get All Unique Values in Column

I have a project using Spring Data JPA that consumes data from a table full of addresses. One of the columns of this table is the city. I would like to get a distinct list of cities that are in the table i.e. SELECT DISTINCT city FROM address.
Is there a way to do this using Spring Data JPA?
This can be achieved using the #Query annotation as:
public interface AddressRepository extends CrudRepository<Address, Long> {
#Query("SELECT DISTINCT a.city FROM Address a")
List<String> findDistinctCity();
}
Then, a call to addressRepository.findDistinctCity() would return the distinct city names.
A sample application is available on Github for review. Run integration test as mvn clean test to verify the approach.
Manish's comment should probably be bumped up to an answer (which i'll try to capture here since it ultimately solved my problem...although projections didn't seem to work with select distinct). The selected answer works in spring-data-jpa, but fails in spring-data-rest. One possible workaround for the spring-data-rest scenario is to create a separate #RestController for the select distinct results
#RestController
public class AddressRepoAdditionals {
#Autowired
private AddressRepository repo;
#RequestMapping("/additional/address/distictCities")
public List<String> findDistinctCity() {
return repo.findDistinctCity();
}
}
perhaps there's a similar but more elegant variation based on #RepositoryRestController
You can use native query.
#Query(value = "SELECT DISTINCT column_name FROM table_name", nativeQuery = true)
List<Type> findDistinctColumnValues();

Spring JPA findBy accent

I am developing a spring-data-jpa application.
I 've ridden the repository with findBy but does not work when I look content with an accent. Does anyone know why?
I am using the following:
Page<Dades> findByNomcomercialIgnoreCaseContaining (#Param ("nomcom") String nomcom, Pageable pageable);
The database is Oracle.
Thanks for your interest.
It's because ignoreCase does not deal with accents. It only compares both String after uppercasing them. See the documentation for more informations.
I don't know any simple solution to ignore accents with Spring Jpa. You coud either :
Remove this parameter in your query, and filter the result in Java afterward (comparing Strings after doing org.apache.commons.lang3.StringUtils.stripAccents).
Use Spring Jpa Specifications. Again, it provides only functionslike upper, like, ... so you have to write your own, depending on what database you are using.
#Param is not required. if you have any query i.e if you are using #Query then we need use #param to pass the specific value releated to query.Below you can check how to use #Query and #Param
#Query("SELECT t.title FROM Todo t where t.id = :id")
String findTitleById(#Param("id") Long id);
if you are not added these annotation use in your repository layer
#Transactional
#Repository
Check another thing i.e
#Transactional
#Repository
public interface IXyzRepository extends CrudRepository<ABC,Integer>{
//some methods you have
}
whether the primary id of class ABC is of type Integer

JPA criteriabuilder group by 1

I'm trying to migrate my postgres native querys to use criteriabuilder instead.
What I want to achieve is:
select date_trunc('day',t.starttime) AS day, count(*) AS no_of_users from login_table t group by 1 order by 1
So far I I don't see how to build the group by 1 order by 1.
This is how far I've gotten:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<RequestPerWeek> cq = cb.createQuery(RequestPerWeek.class);
Root<TLogin> from = cq.from(TLogin.class);
String date = "week";
Expression<Calendar> dateTrunc=cb.function("date_trunc",Calendar.class,cb.literal(date), from.get(TLogin_.starttime).as(Calendar.class));
cq.select(cb.construct(RequestPerWeek.class,cb.count(from),dateTrunc));
I've tried several groupby alternatives, but noone works like I want it to :-|
best regards,
hw
We are using spring data jpa in our project and if you use it, there is no need to write criteria query for simple queries, you can simply write the query directly on top of your method and get the result. This approach is 'Using named parameters'
For example,
public interface UserRepository extends JpaRepository<User, Long> {
#Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(#Param("lastname") String lastname,
#Param("firstname") String firstname);
}
Below link is useful for anyone who is using spring data jpa, if you are writing criteria query take a look if you can get your result using named parameters approach. This is simple and you write very less code.
http://docs.spring.io/spring-data/data-jpa/docs/1.4.x/reference/htmlsingle/#jpa.named-parameters