select distinct values using spring data rest - java-8

I'm using java 8 and spring-data-rest to create API on my data.
I have a table Car(id, name, date...)
I'm trying to have an endpoint to retrieve distinct car names.
here's my Repository :
#RepositoryRestResource(path = "cars")
public interface CarRepository extends JpaRepository<Car, Long> {
//What i want to do
//#Query(value = "select distinct c.name as name from Car c")
#Query(value = "select distinct c from Car c")
List<Car> findDistinctName();
}
The query commented does not work , i have an exception
java.lang.IllegalArgumentException: PersistentEntity must not be null!
apparently this is the normal behavior of SDR.
I tried another solution by using Projections
#Projection(name = "name", types = {Car.class})
public interface CarName {
String getName();
}
but i cant get the distinct values, any idea?
Thank you :)

All you need, to do if you need a distinct list of cars, is such this query method:
public interface CarRepository extends JpaRepository<Car, Long> {
List<Car> findDistinctBy();
}
Spring Data JPA supports the Distinct keyword in repository query methods to set a distinct flag on the query to be created.

I found an (ugly) workaround, using jpql :
#Query(value = "select c from Car C WHERE c.id IN (SELECT min(ca.id) FROM Car ca Group by ca.name)")

I think you should remove the #Query annotation.
Just
List<Car> findDistinctName(); or List<Car> findNameDistinct(); should suffice.
It will automatically generate the query select c.name from Car c

Related

How do I use custom SQL in sprint data repository?

I`m using Repository like this:
public interface UserRepository extends Repository<User, Long> {
List<User> findByEmailAddressAndLastname(String emailAddress, String lastname);
}
But what I need is execute my own sql statement.
select u.* from users u where exists ( select 1 from expires_users where users_id = u.id )
Please, past link references in answers.
I think you can do as pointed in the documentation of Spring Data JPA.
Here is an example:
public interface UserRepository extends JpaRepository<User, Long> {
#Query("select u.* from User u
where exists(select 1 from ExpiredUser e where e.id = u.id)")
Page<User> findExpiredUsers(Pageable pageable);
}
The Page and Pageable parts are for paging results, assuming that this query could return many more results than you would like to process at once. More information on paging results can be found here.

JPA Custom query Delete from multiple tables

I have an custom query for delete records from 2 tables as follows
#Repository
public interface RoamingStatusHistoryRepository extends JpaRepository<RoamingStatusHistory, String> {
#Query("DELETE rsh,rs from RoamingStatusHistory rsh inner join RoamingStatus rs on rsh.msisdn = rs.msisdn where TIMEDIFF(NOW(),rsh.createdDate)>'00:00:30'")
public List<Date> deleteByDate();
}
But after DELETE IntelliJ saying from expected got rsh and after rsh there is a error saying alias definition or WHERE expected, got ','
How to fix this issue. Have researched in the internet but couldn't find a solution
I assume that this query is a native SQL query so you have to add nativeQuery = true
#Repository
public interface RoamingStatusHistoryRepository extends JpaRepository<RoamingStatusHistory, String> {
#Query("DELETE rsh,rs from RoamingStatusHistory rsh inner join RoamingStatus rs on rsh.msisdn = rs.msisdn where TIMEDIFF(NOW(),rsh.createdDate)>'00:00:30'",
nativeQuery = true)
public List<Date> deleteByDate();
}

Hibernate JPA issue doesnt apply IS-A Relationship of table at some times

I have a Parent Table A and extended Child tables B and C
ex:
public class A {
private Long id;
//getters setters//
}
public class B extends A{
private String name;
//getters setters//
}
now at my repository,
public interface B extends JpaRepository<B, Long> {
#Query("select a from A a")//--This works
B getAll()
#Query("select a.id, b.name from A a join a.B b")//-- This doesn't
B getSpecificCols()
}
I need an explanation since "B is an A" that's why getAll() works
how come getSpecificCols() isn't working?
Error is
java.lang.ClassCastException: java.lang.Long cannot be cast to <package>.B
BTW I'm using Hibernate Spring
The query returns a long (a.id) and a string (b.name). The interface assumes that you return an entity (B). The returned id cannot be cast into a B, so you get a ClassCastException. If you want individual fields you can return List<Object[]>, where each record will be an array with id and name. Or you can use a projection (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections).
By the way, does the first query really work when there are A entities in the database that are not B entities, for example if A also has a subclass C? It looks plain wrong to select the base class and return the derived class without filtering. I would select from B to return B.
After reading documentation what I needed all along was to put constructors in my entity/table where you put what specific parameters you need.

Spring data jpa query to return with multiple properties

I have to fetch Users by id and state.The method takes a set of usersIds as input.
I need a jpa query like below:
public Set<Users> fetchUsersByIdsContainingStateId(Set<Integer> userIds, Integer stateId)
Is there a query like the above in Spring Data JPA or I need to resort to named query
you can use spring data query:
public interface UserRepository extends CrudRepository<User, Long> {
Set<User> findUserByIdInAndStageId(Set<Long> userIds , Long stageId);
#Query("select u from User u where u.id in (:userIds) and u.stage.id=:stageId")
Set<User> findUserByUserIdsAndStageId(#Param("userIds") Set<Long> userIds , #Param("stageId") Long stageId);
}
for method findUserByIdInAndStageId spring data generates something
like
-- whereuser0_.id in (? , ? , ?...)) and stage1_.id=?
method findUserByUserIdsAndStageId do the same as findUserByIdInAndStageId , but in Query annotation you should write your query.
second search method findUserByUserIdsAndStageId named just for example , but I'll change it into something more readable like findUserWithStage(......)
PC don't use for domain model plural name like Users , use singular User

Spring Data find by inner relation

My question is about the way Spring data is generating the query .
I have two entities : Message , Sender
#Entity
public class Message extends BaseEntity {
#ManyToOne
protected Account sender;
}
I have a call to
messageDao.findBySenderId(Long id)
The result is query all columns from the two two table with a left outer join between the two tables , but my expectation was simply to just select from message table where sender_id = the passed value.
So is there a way to force selecting only the first message entity and not to join with the other one? I want simple condition in the where clause
by using findBy not custom #Query
You will need a repository like (untested) :
#Repository
public interface MessageRepository extends JpaRepository<Message, Long> {
Message findFirstBySenderId(Long id);
}
See repositories.query-methods
I think Hibernate is doing a LEFT JOIN because your #ManyToOne is optional = true (default).
Try:
#ManyTone(optional = false)
And you will see Hibernate doing a query without a JOIN, as you expected.
You can use fetch type LAZY for the associations types:
#ManyToOne(optional = false, fetch = FetchType.LAZY)

Resources