Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
In which cases we choose SQL, Hibernate Query Language and Criteria API of hibernate?
Criteria Queries are suitable for creating dynamic queries.
For example it is much easier to add some ordering dynamically or leave some parts (e.g. restrictions) out depending on the value of a parameter.
Criteria queries, are defined by instantiation of Java objects that represent query elements not as Strings. The advantage of this is that errors can be detected at compile time. Criteria queries are type-safe
HQL queries are defined as strings, similarly to SQL. Use HQL for static and complex queries, because it's much easier to understand/read.
Also HQL doesn't depends on the table of the database. Instead of table name, we can use Entity name in HQL. So it can be used as a database independent query language.
#Entity(name="MyEntityName")
#Table(name="MyEntityTableName")
class MyEntity {
//A table with name MyEntityTableName is created and the entity name is MyEntityName.
//Your JPQL/HQL query would be :
select * from MyEntityName
Both of these allows you to decouple your application from SQL. SQL syntax can vary depending on the database vendor(Oracle, MySQL .etc). So, if you want to change the underlying database, there will not be any impact(or minimum impact)
There can be vendor specific, optimized SQL features that you could take advantage of but they are not ANSI compliant. ORM tools such as Hibernate takes the responsibility of dealing with them while providing the optimized solution.
SQL queries with JDBC are a bit faster than Criteria queries and HQL. But this performance scarification is well worth for the advantages gained.
Hope this helps.
HQL - this is fit for most queries and easy to read and write.
Criteria - If you don't want to write query then you can use Criteria API.
ex:-
SELECT * FROM employee WHERE emp_id =1
Criteria query will be
Criteria criteria = session.createCriteria(Employee.class)
.add(Restrictions.eq("id", new Integer(1));
Get all employees
List customers = criteria.list();
Other than that API provides pagination, max row id, child object selection etc..
SQL - Other two API not fit your work then go with native SQL.
Related
I have a problem where there are courses that have classes with different days. However, I also have the possible days of having classes. Using Spring Data, I created the Class, DayHour and PossibleDaysClass entities. Using the ORM approach, I would have to create a table to "query" between DayHour and PossibleDaysClass entities. In this case, the question arose of, when to use the entities approach and #JoinTable and when to decide to use an approach as a native query?
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
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.
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.
I am using an IList<Employee> where i get the records more then 5000 by using linq which could be better? empdetailsList has 5000
Example :
foreach(Employee emp in empdetailsList)
{
Employee employee=new Employee();
employee=Details.GetFeeDetails(emp.Emplid);
}
The above example takes a lot of time in order to iterate each empdetails where i need to get corresponding fees list.
suggest me anybody what to do?
Linq to SQL/Linq to Entities use a deferred execution pattern. As soon as you call For Each or anything else that indirectly calls GetEnumerator, that's when your query gets translated into SQL and performed against the database.
The trick is to make sure your query is completely and correctly defined before that happens. Use Where(...), and the other Linq filters to reduce as much as possible the amount of data the query will retrieve. These filters are built into a single query before the database is called.
Linq to SQL/Linq to Entities also both use Lazy Loading. This is where if you have related entities (like Sales Order --> has many Sales Order Lines --> has 1 Product), the query will not return them unless it knows it needs to. If you did something like this:
Dim orders = entities.SalesOrders
For Each o in orders
For Each ol in o.SalesOrderLines
Console.WriteLine(ol.Product.Name)
Next
Next
You will get awful performance, because at the time of calling GetEnumerator (the start of the For Each), the query engine doesn't know you need the related entities, so "saves time" by ignoring them. If you observe the database activity, you'll then see hundreds/thousands of database roundtrips as each related entity is then retrieved 1 at a time.
To avoid this problem, if you know you'll need related entities, use the Include() method in Entity Framework. If you've got it right, when you profile the database activity you should only see a single query being made, and every item being retrieved by that query should be used for something by your application.
If the call to Details.GetFeeDetails(emp.Emplid); involves another round-trip of some sort, then that's the issue. I would suggest altering your query in this case to return fee details with the original IList<Employee> query.