Fetch jpa sql execution plan with #QueryHint and spring data repository - oracle

I am using spring-data for DB interaction. I want to see the jpa sql execution plan for a query written in repository. How can i do it.
https://vladmihalcea.com/execution-plan-oracle-hibernate-query-hints/ tells about using GATHER_PLAN_STATISTICS and COMMENT query hints. I added COMMENT hint but don't know how to add other one.
public interface StudentRepository extends JpaRepository<Student, Long>{
#QueryHints({
#QueryHint(name=org.hibernate.annotation.queryHints.COMMENT,
value="SQL_PLAN_STUDENT")
})
List<Student>findByStudentIDIn(List<Long> ids);
}

The #QueryHints annotation accepts an array constructor like list of #QueryHint items.
So you can add multiple QueryHints by addings them to a comma separated list. For example:
#QueryHints({
#QueryHint(name=org.hibernate.annotations.QueryHints.COMMENT, value="SQL_PLAN_STUDENT"),
#QueryHint(name="GATHER_PLAN_STATISTICS" , value="GATHER_PLAN_STATISTICS")
})
Unfortunately I don't have access to a running instance of a oracle dbms, so I can't check the result of the given hint.

Related

Search for a String in a column of List of Strings using Spring jpa query

I have a Spring Boot application and I am using Spring Data JPA to query a PostgreSQL database.
I have a column of List type in my database. Now I need a query to search all those rows where my input parameter is present in this list.
eg. I have a column of type List containing any of these values: ["cat","dog","cow"].
I need to find all those rows where "cat" is one among the list.
Can you help me with the format of this query? Thanks in advance.
From what I could understand, you have a DB table, let's say Sample. Now this table has multiple columns with one column whose values can be either of "cat","dog","cow". Let's assume the column name to be 'sampleName'.
So, in your code you must be having an #Entity class for Sample with #Column sampleName, and a corresponding JPA repository - SampleRepository.
Now, the code for requirement should look like as shown below:
public interface SampleRepository extends JpaRepository<Sample, Long> {
Optional<Sample> findBySampleName(String sampleName);
}
In above JPA repository, I have assumed that you have an #Id field of type Long in your entity Sample. Also, I have made use of method-name strategy. Spring boot will automatically translate this method name to a SQL query at run time like - SELECT * FROM sample WHERE sampleName = 'cat'. This value cat will be provided to your repository method as an argument from #Service layer.
Hope this helps!
In addition to this, you can also choose to use the native query approach. Please refer - https://www.baeldung.com/spring-data-jpa-query for more details.

Can we make Spring JPA Specifications work with EntityGraph?

I am implementing a dynamic query logic using JPA specifications on an entity. The entity is having multiple relations with other entities. I am running into the issue of generating too many queries while executing JPA specifications.
Is there a way to combine JPA specifications findAll(specification, page) with EntityGraph so that we can one query generated while executing the same?
Yes it is absolutely possible to pass EntityGraph using EntityGraphJpaSpecificationExecutor
#Repository
public interface UserRepository
extends JpaRepository<EntityClassName, DatatypeOfPrimaryKey>, EntityGraphJpaSpecificationExecutor<EntityClassName> {
}
userRepository.findAll(specification, pageable, new NamedEntityGraph(EntityGraphType.FETCH, "graphName"))

join more than one table in spring jparepository

I am trying to fetch record by doing a join. I am new to spring jparepository.
I understand that there is separate repository for each entity(table) where when i implement i need to define the entity and datatype of primary key.
Could anyone please suggest how can I fetch record by joining two tables.
I have two repo as below:
public interface AEntityRepository extends JpaRepository<AEntity, Integer>
public interface BEntityRepository extends JpaRepository<BEntity, Integer>
I want to join above two entity(AEntity, BEntity).
I know I can have custom query using something like below:
#Query("SELECT ****** FROM AEntity ae")
AEntity findCustomrRecords();
However can I write the same kind of query (join query) with join.
Do i need to have a separate repository implementing some other class.
Can anyone please help.
I am using mysql.
I understand that there is separate repository for each entity(table)
This is a very common misunderstanding. You do not want to have a repository per entity, but per aggregate root. See http://static.olivergierke.de/lectures/ddd-and-spring/
Regarding your specific problem at hand: Creating a custom method in your repository interface and annotating it with a JPQL should do the trick. So you get something like:
#Query("select a from BEntity b join b.a a where b.foo = :foo")
AEntity getAllFooishAs(String foo);
You can use any join syntax JPQL offers in the query.

Is there a way to use UPDATE query with dynamic attributes in Spring Framework?

I'm developing a REST server application using Spring Boot.
Just got a question while constructing an UPDATE query.
Currently my UPDATE query in UserRepository is like this;
#Modifying
#Transactional
#Query(value ="update User u set u.user_dob=:userDOB, u.user_lastname=:userLastName, u.user_firstname=:userFirstname, u.user_streetaddress=:userStreetAddress where d.driver_id=:driverId", nativeQuery = true)
void updateUser(#Param("userDOB") String userDOB, #Param("userLastName") String userLastName, #Param("userFirstName") String userFirstName, #Param("userStreetAddress") String userStreetAddress);
However, I don't like to list all the attributes of User in one UPDATE query.
Is there anyway to construct UPDATE query dynamically?
For example;
Update with
set u.user_dob=:userDOB, u.user_lastname=:userLastName, u.user_firstname=:userFirstname, u.user_streetaddress=:userStreetAddress
or
u.user_lastname=:userLastName, u.user_firstname=:userFirstname
using one update method.
If you are using Spring Data JPA (seems you do), your repository interface is probably extending JpaRepository interface.
In this case, you could simply use save method.
Here are some good examples:
http://www.springbyexample.org/examples/spring-data-jpa-repository.html
http://www.springbyexample.org/examples/spring-data-jpa-code-example.html

Database specific queries in a Spring Hibernate application

In a dao class implementation,I want to use different sql query depending upon the underlying database. Since my SQL query is complex which selects from a database view and uses "UNION" key word and uses database specific functions, I can not use JPQL (or HQL). I did some search on Stackoverflow and threads suggest the good way would be to find out the dialect used in the application. Can anyone provide some code example?
EDIT : My apologies, I did not explain my question well enough. In my dao class implementation , I want to determine the database ( say mysql or oracle) on which my application is running and then execute the appropriate query. I need the code like jdbcTemplate.findOutTheDialect().
JPA have the native queries for that.
An example you can find here.
You can use spring JdbcTemplate to connect and query from your database.
For Example..
String query = "SELECT COUNTRY_NAME FROM COUNTRY WHERE MCC_COUNTRY NOT IN ('Reserved') ORDER BY COUNTRY_NAME";
jdbcTemplate.query(query, new ObjectRowMapper());
Where "ObjectRowMapper" will be a class to map return resultset to list of Objects.

Resources