Database specific queries in a Spring Hibernate application - spring

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.

Related

Spring JPA Derived query method groupBy

Hi I was building an app and was wondering on how I can convert this query into a derived query method without using the annotation #Query:
SELECT address, COUNT(*) address FROM `employee` GROUP BY address ORDER BY address DESC LIMIT 5
I have tried it here is how I did it
List<Employee> countByAddressGroupByAddressByOrderByAddressDescLimit5();
This throws the following error
Invalid derived query! No property groupByAddressBy found for type String! Traversed path: Employee.address.
I was wondering if what am I doing wrong here thank you in advance.
I don't think query derivation supports group by.
You can't.
Derived queries don't support GROUP BY.
Derived queries are intended only for simple queries, where the mapping between a normal method name that you might choose independently from Spring Data and the query needed for implementation is obvious.
For more complex cases like the one you describe other mechanisms are available, like annotated or named queries. Nobody wants to use a method name like countByAddressGroupByAddressByOrderByAddressDescLimit5 anyway.
As others said, derived queries do not support this. There might be other reasons besides simply not being a 'practical' solution.
AFAIK derived query methods are restricted to retrieving instances just for the entity type managed by the repository (you can retrieve MyEntity, Optional<MyEntity>, Collection<MyEntity>, etcetera) or projections that match the fields/columns used for the managed entity.
When you use 'Group By', you break with this resultset structure, you usually have to explicitly indicate which columns you want to retrieve or which operations you want to perform on the grouped columns (which would be impossible using just a method name).
TL;DR
You can't easily indicate the columns you want to include in a 'Grouped By' query result, so no, I don't think there is a way to use this technique with 'Group By'.

Ignite SQL tool query for collections within object

I am using Ignite v2.1 and dbeaver to query caches. Is it possible to query collections within a objects in the cache, or complex object within object in the cache? And if so, what it the syntax?
For example, if I have a cache such as IgniteCache and Person looked like the following, what would the syntax be to 1) select the address and 2) select the siblings names & addresses?
class Person {
String name;
Addresss address;
Collection<Person> siblings;
}
It is not possible to do SQL over nested collections in Ignite: SQL standard does not support such things. SQL tables are flat.
Think regular SQL databases: you need to introduce Person.id and Person.parentId (for one-to-many), or a separate mapping table (for many-to-many), then use SQL JOIN to query siblings.
You will have to declare QueryEntity for this cache, with list of fields and indexes on this cache, then you can use its fields in SQL queries. Annotations driven setup is explained in the same doc, pick one which suits you better.
Then the 1) will probably be something like SELECT ADDRESS FROM PERSONCACHE.PERSON WHERE NAME = ?.
Foreign keys are not supported, however, and I'm don't think that siblings setup will work. It doesn't work like that for relational databases unless you add join tables. Ignite is not a graph database.

Optimizing Hibernate layer

After moving the logic from a legacy application (SQL/coldfushion) to Spring Rest with Hibernate, we have experienced a slowness in the application. The main reason is with Hibernate we noticed many queries are generated which we used to do with one single query in the legacy application (two pages long query).
Write now, I'm looking at selecting proper fetch strategies and try to optimize code. Could you please give me any other areas that I need to investigate to optimize the Hibernate layer or any other sujjestions?
Try to use DTO not entities(you can load DTO directly from the database)
Review the loading strategy (Eager or Lazy)
Try to use Native Queries more
Try to use more parameters to restrict the result set
You also can leverage some caching technique (cache all static data)
Try to implement hashCode and equals for each entity
If you use, HQL queries, then add the 'join fetch', It avoids the n+1 query problems. For more information on join fetch
e.g:
select a from Model a
inner join fetch a.b as b
Add 'indexes' for columns which are using in where condition.
e.g: Add index for the column 'name' which is used in where condition.
select a from Model a where a.name ='x'
Follow the below links:
http://www.thoughts-on-java.org/tips-to-boost-your-hibernate-performance/
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html

how to do AND and multiple OR parameters method in spring data JPA

I am trying to formulate a method name for this query :
#Query("from Employees where department = ?1 and (fullTime = true or contractor = true or subContractor = true)")
I thought this method will do the trick, but it does an and on dept and full time
public List<Employees> findByDepartmentAndfullTimeTrueOrContractorTrueOrSubContractorTrue(String dept);
This is a related question : Spring JPA Data "OR" query but was asked in 2012. Is there a way to achieve this without having to use #Query ?
This is currently not supported and probably never will be for a very simple reason:
Derived queries are considered a means to define very simple queries. I admit this is blurry but if you get to findByDepartmentAndfullTimeTrueOrContractorTrueOrSubContractorTrue it's time to rethink whether that's actually what you want to expose to clients. It's awkward to write, awkward to read and probably actually more than a collection of predicates but conveying a higher-level meaning and thus should be named in amore descriptive way.
The solution - as you already discovered - is to use #Query or Querydsl predicates.

Calling Oracle User defined function in Hibernate HQL

Can anyone help me here. I want to call an oracle function in Spring+hibernate application.
How this can be done.
Eg: Oracle Function olddata(Varchar2 serialNumber)
This returns set of records having xyz fields. I need to call this function in hibernate using HQL. Also, the function have 2 tables in it using join and records are fetched from both these tables.
Regards,
Parichaya
I think this blog exactly describes what you need. (Basically you need to create your own Hibernate dialect - which sounds scary at first but not a big deal actually).

Resources