Spring Data JPA Select Distinct Column Pageable - java

I'd like to select distinct records based on a column where not null and return a page. The following is throwing java.sql.SQLSyntaxErrorException: ORA-01791: not a SELECTed expression.
(If I can get this to work I'd like to select distinct by a few additional columns.)
#Query(value="SELECT DISTINCT pm.batchId from PrintManifest pm",
// + "where pm.batchId is not null"
countQuery = "select count(DISTINCT pm.batchId) from PrintManifest pm",
nativeQuery = true
)
Page<PolicyPrintManifest> findDistinctBatchId(Pageable pageable);
I also tried with no luck:
Page<PolicyPrintManifest> findDistinctByBatchIdExists(Pageable pageable);
What's the right way to do this query?

Is PrintManifest name of the table or the entity. Remember that in native query, you have to use table name not entity name

Related

JQPL select inside select

just switched to spring boot from .NET Core, in .NET core we can easily nest a select inside a select like this:
var result = from c in context.Cars
join br in context.Brands
on c.BrandId equals br.Id
join col in context.Colors
on c.ColorId equals col.Id
select new CarDetailDto
{
Id = c.Id,
BrandName = br.Name,
CarName = c.Name,
ColorName = col.Name,
DailyPrice = c.DailyPrice,
ModelYear = c.ModelYear,
CarImages = (from cimg in context.CarImages
where cimg.CarId == c.Id
select new CarImage
{
Id = cimg.Id,
ImagePath = cimg.ImagePath,
CarId = c.Id,
Date = cimg.Date
}).ToList()
};
I want to do that in JPQL as well but didnt manage to solve
#Query( select column1, column2, column3 from tablename1 where coluname=(select columname from tablename2 where columnname=abcd) )
Your JPQL query should look like above.
Whatever subquery you write with condition.
If your query is fetching 3 column you need to create a DTO with same column name.
If your query is fetching list of rows then your actual jpql will look like this.
#Query( select column1, column2, column3 from tablename1 where coluname=
(select columname from tablename2 where columnname=abcd) )
List<ResultDTO> findAllResultList(Parameter value);
Above it is mapping the result to list of DTO objects to result rows.
If your query is fetching single row then your actual jpql will look like this.
#Query( select column1, column2, column3 from tablename1 where coluname=
(select columname from tablename2 where columnname=abcd) )
ResultDTO findResult(Parameter value);
The single result is mapped to one DTO object.
Make sure your result column name and DTO column name matches
Using the JPA repository call the names of the method which you used for the particular query.

Hibernate not Injecting Parameters in Query Annotation

I've read the documentation on inserting method parameters into queries and other questions however they all suggest that this should work.
#Query(value = "SELECT * FROM period WHERE time LIKE \":day%\" AND id IN (SELECT id FROM booking)", nativeQuery = true)
List<Booking> findAllBookingsOnDay(#Param("day") String day);
Results in:
Hibernate: SELECT * FROM period WHERE time LIKE ":day%" AND id IN (SELECT id FROM booking)
I've tried removing quotations and percentage but that just results in.
Hibernate: SELECT * FROM period WHERE time LIKE ? AND id IN (SELECT id FROM booking)
The correct way to do this is to just use an unescaped placeholder in the query, and the bind the LIKE wildcard expression to it from the Java side.
#Query(value = "SELECT * FROM period WHERE time LIKE :day AND id IN (SELECT id FROM booking)", nativeQuery =true)
List<Booking> findAllBookingsOnDay(#Param("day") String day);
Usage:
String day = "%friday%"; // or whatever value would make sense here
findAllBookingsOnDay(day);

How to retrieve data and count of data at same time in hql?

I want to retrieve count and list of data in one query only which I want to write on JPA repository. I wrote it using a constructor and executed using entity manager, but it didn't work. It gave me a QuerySyntaxException. Here is my query:
String hql = "select new core.abc(select count(*) from abc as m where m.Id in :Ids and m.Type = :Type,"
+ "select max(m.modificationTime) from abc as m where m.Id in :Ids and m.Type = :Type )";
How can I write such kind of query in JPA repository?
I just figure out your use case senario is that you want to get all records from table as well as total-count of records and max value of a specific column , you named that column as modificationTime. So onething will be happen in this case, if you want to intract with table with single query, Than you will get useless data for both column named as max and count.
Try This for JPA,
#Query(value="SELECT cb from abc cd where cd.Id in (?1) and cd.Type=?2 , (SELECT MAX(m.modificationTime) as maxModificationTime , COUNT(*) as count FROM abc m where m.Id in (?3) and m.Type=?4) as m",nativeQuery=true)

How to pass parameter on jpa query?

I have two entities Like SmsOut and SmsIn. The relation between two entities contains OneToMany where smsIn.id is primary key and smsOut.sms_in_id is foreign key.
Now I want to pass parameter like smsIn.mobileNumber, smsIn.smsText and so on, on the query
SELECT so FROM SmsOut so order by id desc
Following is my database diagram:
Edited
Following is my code :
String sql = "SELECT so FROM SmsOut so WHERE so.smsInId.mobileNumber =:mobileNumber AND so.smsInId.smsText =:smsText AND so.smsInId.shortCode =:shortCode between so.smsOutDate =:startDate and so.smsOutDate =:endDate order by id desc";
Query query = em.createQuery(sql);
query.setParameter("mobileNumber", mobileNumber);
query.setParameter("smsText", smsText);
query.setParameter("shortCode", shortCode);
query.setParameter("smsOutDate", startDate);
query.setParameter("smsOutDate", endDate);
smsOutList = query.getResultList();
and exception is :
SEVERE: line 1:188: expecting "and", found '='
java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException: expecting "and", found '=' near line 1, column 188 [SELECT so FROM com.f1soft.SMSC.entities.SmsOut so WHERE so.smsInId.mobileNumber =:mobileNumber AND so.smsInId.smsText =:smsText AND so.smsInId.shortCode =:shortCode between so.smsOutDate =:startDate and so.smsOutDate =:endDate order by id desc]
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:624)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:96)
Please Help me.
Thanks
You haven't explained the JPA relationship between SmsIn and SmsOut, so I'll assume SmsOut has a getSmsIn() with a relation on the id field.
When you have an EntityManager em, you can call em.createQuery, which is like SQL prepare, and then setParameter:
TypedQuery<SmsOut> q = em.createQuery("SELECT so FROM SmsOut so WHERE so.smsIn.mobileNumber = :number ORDER BY id DESC");
q.setParameter("number", "12345678");
List<SmsOut> results = q.getResultList();
See the Javadoc for Query for the different ways you can specify the parameters.
SELECT so FROM SmsOut so WHERE smsIn.mobileNumber = ? AND smsIn.smsText =? order by id desc
Replace the ? sign with the apropiate values.
between is the problem:
between so.smsOutDate =:startDate and so.smsOutDate =:endDate
try
so.smsOutDate between =:startDate and =:endDate

Select top 1 result using JPA

I need to bring from DB only one single result. How can I do that with JPA?
Select top 1 * from table
I tried
"select t from table t"
query.setMaxResults(1);
query.getSingleResult();
but didn't work. Any other ideas?
Try like this
String sql = "SELECT t FROM table t";
Query query = em.createQuery(sql);
query.setFirstResult(firstPosition);
query.setMaxResults(numberOfRecords);
List result = query.getResultList();
It should work
UPDATE*
You can also try like this
query.setMaxResults(1).getResultList();
To use getSingleResult on a TypedQuery you can use
query.setFirstResult(0);
query.setMaxResults(1);
result = query.getSingleResult();
2021 att: you can use TOP or FIRST in Spring Data JPA
example:
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);
doc: https://docs.spring.io/spring-data/jpa/docs/2.5.4/reference/html/#repositories.limit-query-result
The easiest way is by using #Query with NativeQuery option like below:
#Query(value="SELECT 1 * FROM table ORDER BY anyField DESC LIMIT 1", nativeQuery = true)
Use a native SQL query by specifying a #NamedNativeQuery annotation on the entity class, or by using the EntityManager.createNativeQuery method. You will need to specify the type of the ResultSet using an appropriate class, or use a ResultSet mapping.

Categories

Resources