Annotation jpa #Query - sql

I am studying jpa and hibernate. I see in the repository class:
#Query(value = "FROM AccountTable")
List<Account> findAllAccount();
Is #Query(value = "FROM AccountTable") equal to a select * from AccountTable, without filters? Is it correct?

First of all, #Query is not jpa, but spring data jpa annotation.
According to the hibernate documentation:
The select statement in JPQL is exactly the same as for HQL except that JPQL requires a select_clause, whereas HQL does not.
So, the mentioned in your question query with HQL specific syntax equals to the following JPQL:
#Query("select a FROM AccountTable a")
List<Account> findAllAccount();
Please note that the last one query is more clear and suggested as a good practice.
Even though HQL does not require the presence of a select_clause, it is generally good practice to include one. For simple queries the intent is clear and so the intended result of the select_clause is easy to infer. But on more complex queries that is not always the case.
It is usually better to explicitly specify intent. Hibernate does not actually enforce that a select_clause be present even when parsing JPQL queries, however, applications interested in JPA portability should take heed of this.

Related

Which is a efficient way to query a database in Grails? SQL, HQL or GORM?

I am working on a application where I need to query(simple as well as complex) on a database many times.
I can understand that for simple queries there won't be a substantial difference between any of the approach mentioned above.
I would like know the efficient way in case of semi complex and complex queries.
Suppose I have a Domain class say
Class Sample{
String firstName
String lastName
long timeStamp
}
Now, I want to get the latest two records.So either I can write an
SQL query
select first_name, last_name from sample order by time_stamp desc limit 2;
HQL query
String queryString = "select firstName, lastName from Sample order by timeStamp desc"
List sampleList = Sample.executeQuery(queryString, [max: 2, offset: 0])
GORM query
def list = Sample.list(max: 2, sort: "timeStamp", order: "desc")
Out of this which will be the efficient way to query a database?
There is no significant difference between these 3. If you turn on query logging you should see that the SQL is virtually the same in all 3 cases.
However, if using HQL or GORM you can cache the results of the query. This might lead to greater efficiency if the query frequently returns the same results. On the other hand if the query rarely returns the same results (e.g. because the sample table is frequently updated), enabling query caching may reduce efficiency.
Ultimately, worrying about performance at this level is likely a case of premature optimization. I'd advise doing the simplest thing, which is probably GORM in this case, and worry about performance only when a performance problem has been identified.
The fastest and most performant way would be to use dialect-specific SQL queries and no ORM at all.
In GORM/Hibernate there's no substantial differences between those ways, what is more important is the code readability. In this case the criteria queries win over SQL/HQL counterparts, unless findAllBy* can be applied.
As injecteer mentioned before, the native SQL query is always the most efficient way to get the requested results.
All other approaches depend the implementation of the GORM-Datastore resp. the Query-mapping implementation. Both (the HQL and the critera) queries need to be translated to a native SQL-dialect (if using a SQL-Database) before the query is send to the database. In the given example both queries will result in the same native-SQL statement.

Avoid string concatenation to create queries

Martin Fowler in his book Patterns of enterprise application architecture says
A good rule of thumb is to avoid string concatenation to put together
SQL queries
It is a practice that I use quite often, to abstract the syntax of my SQL queries from the real data of the query.
Can you explain me why this is considered a bad practice?
While there might be usecases where you build a prepared statement by string-concatenation before compiling it, it is always bad practice to insert query-parameters using string-concatenation for two reasons:
Performance: When using a prepared statement the query-syntax has to be parsed only once and the access-path has to be calculated only once for each distinct query-type. When building statements by string-concatenation parsing and optimizing has to be done for each execution of the query.
Security: Using string-concatenation with data provided by the user is always prone to SQL-injection-attacks. Suppose you got a statement:
query = "select secret_data from users where userid = '" + userid_param + "'";
And imagine someone sends a userid_param containing "' OR 1=1;"...
This way the only way to defend is doing 100% correct input-sanitation which might be quite hard to get right depending on the language used. When using prepared statements with a properly implemented driver the driver will isolate the statement form the query-parameters so nothing will be mixed up.

NHibernate problem choosing between CreateSql and CreateCriteria

I have a very silly doubt in NHibernate. There are two or three entities of which two are related and one is not related to other two entities. I have to fetch some selected columns from these three tables by joining them. Is it a good idea to use session.CreateSql() or we have to use session.CreateCriteria(). I am really confused here as I could not write the Criteria queries here and forced to use CreateSql. Please advise.
in general you should avoid writing SQL whenever possible;
one of the advantages of using an ORM is that it's implementation-agnostic.
that means that you don't know (and don't care) what the underlying database is, and you can actually switch DB providers or tweak with the DB structure very easily.
If you write your own SQL statements you run the risk of them not working on other providers, and also you have to maintain them yourself (for example- if you change the name of the underlying column for the Id property from 'Id' to 'Employee_Id', you'd have to change your SQL query, whereas with Criteria no change would be necessary).
Having said that- there's nothing stopping you from writing a Criteria / HQL that pulls data from more than one table. for example (with HQL):
select emp.Id, dep.Name, po.Id
from Employee emp, Department dep, Posts po
where emp.Name like 'snake' //etc...
There are multiple ways to make queries with NH.
HQL, the classic way, a powerful object oriented query language. Disadvantage: appears in strings in the code (actually: there is no editor support).
Criteria, a classic way to create dynamic queries without string manipulations. Disadvantages: not as powerful as HQL and not as typesafe as its successors.
QueryOver, a successor of Criteria, which has a nicer syntax and is more type safe.
LINQ, now based on HQL, is more integrated then HQL and typesafe and generally a matter of taste.
SQL as a fallback for cases where you need something you can't get the object oriented way.
I would recommend HQL or LINQ for regular queries, QueryOver (resp. Criteria) for dynamic queries and SQL only if there isn't any other way.
To answer your specific problem, which I don't know: If all information you need for the query is available in the object oriented model, you should be able to solve it by the use of HQL.

HQL vs. SQL / Hibernate netbeans HQL editor

I am teaching my self hibernate, and am quite confused of why i can not just write simple SQL queries.
I find it rather more confusing to use than plain SQL (what I am used to)
PLUS: The NetBeans HQL editor I found pretty annoying, It is harder for me to produce a right query in HQL, then in SQL, and why does the shown SQL differ from actual SQL statements ?
So why use it ? - As it is known that hibernate is very resource extensive, and I believe that hibernate is the reason for our app to running out of memory very often, as during the process of redeploying e.g...
I am very interested in knowing why I should use Hibernate and not plain SQL (mysql) statements !?
And maybe a good link for hibernate queries would be nice ;), I am using this one atm:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html
But also interested in any good link explaining the setup of the queries, the mapping, underlying construction etc..
Best Regards
Alex
HQL is object oriented and it's done with the purpose of working on the Java objects representing your DB tables.
A basic advantage is that you can put placeholders like :orderNumber (using the colon simbol) in the HQL query and replace with the value of a variable. For example:
int orderNumber = 685412;
List<Order> l=
session.createQuery("from Order where orderNumber = :orderNumber")
.setParameter("orderNumber",orderNumber).list();
In this way you can modify orderNumber in a simple way, evoiding the classical
String query = "select * from Order where orderNumber = " + orderNumber + "...";
Morover using MySQL syntax would sometimes turn your code not reusable if you migrate your DB to another DBMS.
Anyway I'm still not so convinced about the preference on HQL.
Here you can find the full grammar definition.

NHibernate and reporting

I am building a website on top of nhibernate. Is there any efficient way to build reports? BY reports, I mean is there anyway to execute a complicated query that grabs random pieces of data? Stored procedures? Hql?
Can I get single, non mapped values from hql?
Yes you can.
For simple stuff you can use HQL and select stuff into a new non-mapped object (its class must be "registered" with NH but there is no mapped per se). HQL syntax looks like
select new NonMappedClass(column1, column2). You need an appropriate constructor to use this.
Reporting with HQL quickly breaks down. I often find myself knowning exactly what to do in SQL but having hard time figuring out the HQL way. Also the lack of real software tools for HQL slows you down (sorry NH Query Analyzer does not cut it). In these case, you can define a raw with an associated . When executing these queries, NH will return you a IList of array of Object. You need the cast the Object() into the proper type. You'll want this for advanced reporting queries.
This casting stuff is error prone and sucks big time. So you they did a nice AliasToBean query transformer that can map the result set column name to a property (names must match of course). I don't know about the latest NH release, but the older 1.2.1 AliasToBean converter seemed to have a bug in which it would converter nullable value type to the default value of the type instead of setting it to null. ie: int? would be 0 instead of null if the associated DB field was null. This prevented me from using AliasToBean in some case and I had to map by hand.
Best advice is don't fall into the trap of performing complex reporting with your business object and for loops. I've seen this in production. It will be a performance horror as your tables grows in size.
Yes, you can do this. It's called dynamic instantiation. The syntax in HQL is
select new MyClass(cust.age)
from customers cust
Or, with Criteria:
.SetProjection(Projections.ProjectionList()
.Add(Projections.Name("cust.age"), "age")
.SetResultTransformer(Transformers.AliasToBean<MyClass>())
Remember, you must have a matching constructor on MyClass!