Class-based projection with native query - spring

Is it impossible to use class-based projection in Spring Data repository with native query?
And how?
PS: I tried to use #Query(value = "select new package.Foo(id, name) from my_table, nativeQuery = true) but it does not work.

I found the solution.
Need to use #SqlResultSetMapping, ConstructorResult and NamedNativeQuery.

Related

How to use Customize your Queries in JPA with Query Methods (spring boot)

I want to retrieve a specific value from the database based on a criteria without using the query method in Spring JPA.
they query desired is
SELECT TOP 1 * FROM Co2 WHERE Co2.room = ?1 order by co2.id desc
which can be used in a normal native query annotation like so:
public interface Co2Respository extends CrudRepository<Co2, Integer> {
#Query("SELECT TOP 1 * FROM Co2 WHERE Co2.room = ?1 order by co2.id desc",
nativeQuery = true)
Co2 findLastInsertedValueForRoom(int id);
}
the question is how to achieve the same using the custom query method in Spring JPA
I will answer my own question,
the equivalent custom method for the query mentioned above is:
Co2 findTopByRoomOrderByIdDesc(Room room);

How to get top results using specifications in spring data jpa?

I am quite new to spring data jpa. I am trying to use specifications while querying database. My question is using crudrepository we can method like :
findTopByUsernameOrderByUpdatedAtDesc(String username);
How can I achieve the same using specifications? I can do basic things like and or in specifications, but not very robust like we can do with criteria etc.
Specification<CustomClass> spec = Specifications.where(specification).and(username);
List<CustomClass> list = findAll(spec);
This was done as follows :
Pageable pageable = new PageRequest(0, 1, Sort.Direction.DESC, "username");
Page oneElementPage = repository.findAll(spec, pageable);
This will sort the data on username column in descending direction and return first result.
You can't express this in a Specification directly. But you can use a Pageable for this:
Page oneElementPage = repository.findAll(spec, new PageRequest(0, 1));
Gives you a Page with a single element.

How to make a custom sorting query in spring boot for a mongo db repository?

I want to put this query with #Query annotation in my repository.
This is the query:
`db.report.find({'company' : 'Random'}).sort( { 'reportDate' : -1} ).limit(1)`
Which is the best way to implement custom queries with #Query annotations or to use MongoTemplate ?
Using Mongo Template.
Criteria find = Criteria.where("company").is("Random");
Query query = new Query().addCriteria(find).with(new Sort(Sort.Direction.DESC, "reportDate"));
BasicDBObject result = mongoOperations.findOne(query, BasicDBObject.class, "collection_name");
Using Mongo Repository
Report findTopByCompanyOrderByReportDateDesc(String company)
Note that in the new version of Springboot(v2.2.5), the correct method is sort.by().
like this:
Query query = new Query().addCriteria(find).with(Sort.by(Sort.Direction.DESC, "reportDate"));

Run two #NamedNativeQuery query on same entity Class

I want to define two #NamedNativequery on entity class . When tying to define eclipse gives a error.
Duplicate annotation of non-repeatable type #NamedNativeQuery. Only
annotation types marked #Repeatable can be used multiple times at one
target.
From that error , I know we cannot define two define two #NamedNativeQuery of the entity class like
#Entity
#Table(name = "abc")
#NamedNativeQuery(name = "ABC.getSomeMethod1" query = "some_query",resultSetMapping ="abcDTO")//1st name query
// #NamedNativeQuery(name = "some_name" query = "some_query",resultSetMapping ="some_dto")//try to define second query , but gives error
public class ABC {
}
I am using spring repository at dao layer to called the method which bind with this query
public interface SomeInterface extends JpaRepository<ABC, Long> {
#Query(nativeQuery =true)
List<ABCDTO> getSomeMethod1(#Param("someParam1") long someParam1, #Param("someParam2") String someParam2);
}
The senario is that I want to run the 1st native sql (which run fine) query and then run the 2nd native sql query(want to run this also from same). How to solve this or What is the possible solution.
If this way I cannot run the two native sql query then is there any other to achive this.
You can define multiple named queries like this
#NamedNativeQueries({
#NamedNativeQuery(name = "ABC.getSomeMethod1"
query = "some_query",resultSetMapping ="abcDTO"
),
#NamedNativeQuery(name = "some_name"
query = "some_query",resultSetMapping ="some_dto"
)
})
Then in the business layer under the transaction you can call these two queries one after another,
If its a simple join between two entities and select and display better go with join's. Always remember to have those columns index in the Table ;)

Can I limit the result of JPQL to just return one result?

I would like to do something like this (in Spring Data JPA) in a repository interface:
interface myRepository extends JpaRepository<A, Long> {
#Query("select a from A a where a.x = :x")
A findFirstBySomeCondition(int x);
}
But I only need the first result. (Edited: The actual query condition is much complex so I would prefer to use #Query instead of findFirst or findTop...)
I don't want to use criteria api, because it's verbose.
I don't want to use the the native query cause I will have to compose the query string manually.
So, is there an solution left though, given the restricted requirement above?
Thanks!
The results of query methods can be limited via the keywords first or top, which can be used interchangeably. An optional numeric value can be appended to top/first to specify the maximum result size to be returned.
interface myRepository extends JpaRepository<A, Long> {
#Query("select a from A a where a.x = :x")
Page<A> findFirstBySomeCondition(#Param("x") int x,Pageable pageable);
}
Impletation Class:
Page<A> results = repository.findFirstBySomeCondition(x,new PageRequest(0, 1));
A object = results.getContent.get(0);
You can use a Pageable for that. The documentation schows different ways of using it: http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.limit-query-result

Resources