Why the inserting explicit values is not allowed in HQL? - java

As it mentioned in Hibernate ORM 5.2.13.Final User Guide:
Only the INSERT INTO …​ SELECT …​ form is supported. You cannot specify explicit values to insert.
Is the reasoning behind it elaborated by official sources? Is there any certain limitation that interferes a support of the INSERT INTO ... VALUES ... form in HQL?

The primary reason why DML-style operations have been introduced is the ability to process multiple records in the database at the expense of one (or just a few in some cases involving entity hierarchies) real SQL statement. This way we can avoid fetching all affected data in-memory to perform equivalent logic using CRUD operations on single entities (rows).
Basically this allows us to use familiar UPDATE and DELETE statements from the SQL world in cases where it is needed, while still utilizing all the benefits of HQL/JPQL.
insert ... select also serves that purpose, while insert ... values would provide no benefit comparing to simply persisting an entity instance.

Related

Hibernate - join tables without NamedNativeQuery

While joining multiple tables on my project using Hibernate jpa /Spring (annotation driven), I had to use the NamedNativeQuery annotation to achieve my objective to extract a distributed resultset spanning multiple tables. This may be a question that merely serves academic merit, but given that I am starting out on Hibernate - is there another way to achieve table joins without having to fall back on queries native to the database dialect?
Yes. I believe this is exactly what you need: https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/querycriteria.html#querycriteria-tuple
Criteria Queries is a way of building a complete query just using its API. If I were you, I'd give it a try.
By the way, according to your question, the reason for using native queries is just for retrieving a specific set of columns. If this is the case, you can also write it using HQL as well. The query doesn't necessarily needs to be native.

How many ways Hibernate provide to access database?

How many ways Hibernate provide to access database?
For example, I want to CRUD an object to database, I found out:
Using session from SessionFactory:
session.save(object);
...
Using Hibernate Query Language.
Using Hibernate Criteria Queries.
Using Native SQL.
But I don't know what I should use. Please list your practice to access database in PRIORITY DECREASING ORDER and the reason why you do that.
Thank you.
If you have an ID and wants the associated entity, the use Session.get(). It's efficient, and makes use of the first-level cache to avoid reexecuting the query again and again.
If you need to get entities via other criteria (like all the users with a given first name, for example), then use JPQL queries. They are simple to write, very readable, and have less limitations than criteria queries.
If you need to take various optional criteria (like for a complex search form), the criteria API is the tool for the job. But it can't do everything a JPQL query does. There are other APIs available, and you can relatively easily write an API that generates dynamic JPQL queries if needed.
If you have a really complex query that can't be expressed using JPQL, then use SQL.
To write things to the database, queries should generally not be used, except in very specific circumstances where many entities must be modified the same way. Instead, get the entities to modify, and modify them. Hibernate will save their new state automatically.

Why do we need to create native query?

I am working in a project which uses JPA ORM and framework provides two kinds of method to create queries.
entityManager.createQuery(query1);
entityManager.createNativeQuery(query2);
I understand the kinds of query string is to be passed to use them, but I don't know exactly why do we need to create native query? Probably we don't want to use ORM capabilities there?
You do not need to create a native query unless you want to. JPQL eventually is translated into SQL by the framework but the framework lets you call the native query also. Why would want to do that:
Low level access, which means that you can optimize and handle the mapping by yourself; with SQL you actually access the database table while with JPQL you access the entity objects;
Maybe you do not want to learn JPQL if you already know SQL
You already have the queries written in SQL, and do not have resources/time to port them to JPQL
createQuery uses JPAs own query language, you select from Class names instead of table names. This is not SQL, it is just similar, and is later transformed to real SQL. Mapping to java classes will be done automatically and actual class instances will be returned as result.
createNativeQuery uses real SQL, and will not be able to use JPA features. This method is used in general if you need to do something really odd that is not supported by JPA. A list of Object[] will be returned, and mapping to java objects will have to be done manually. In other words, its just like working with a DB before JPA came to, just slightly more convenient since connection handling is done automatically.
I have used it for optimization purposes. Using Native queries means that the ORM mapping is not in place, and instead of JPQL, you use the DB's native syntax. So, as #RasmusFranke also pointed out, if you need something that is not supported by JPA (like when you want to use DB vendor specific extensions, which is conceptually a bad idea, since JPA is all about being DB agnostic, but happens nevertheless. I know...)
The other effect of this is that by using native queries, only the supplied query is run. No eager fetching of other entities, or other unwanted stuff. This way, if you deal with huge amounts of objects, you can save some heap space.

Hibernate... how does one do database/SQL queries?

I (think I) understand that Hibernate offers me access to a relational database essentially as if I had a class(es) that matched whatever view(s) I define of some tables.
How do I get the results of a specific query to be accessible via a class? In particular, can I issue a complex SQL query, and process multiple results?
Do I lose any of the power of SQL by using Hibernate?
I (think I) understand that Hibernate offers me access to a relational database essentially as if I had a class(es) that matched whatever view(s) I define of some tables.
Hibernate provides a framework allowing to map an object model to your database and an API to manipulate data through this object model.
How do I get the results of a specific query to be accessible via a class? In particular, can I issue a complex SQL query, and process multiple results?
I'm not sure I understood the question but let's see. The Hibernate way would be to use HQL (Hibernate Query Language) queries and/or Criteria queries to perform queries on the object model.
But you can also use Native SQL (sacrificing portability) to return entities, multiple entities or even non-managed entities (see also Hibernate 3.2: Transformers for HQL and SQL).
Do I lose any of the power of SQL by using Hibernate?
HQL and the Criteria API are quite powerful - and portable - and will generate the proper SQL for your backend. If required, you can still use native SQL queries as already mentioned. But in most cases, HQL and Criteria work well and should be preferred.
See also
14. HQL: The Hibernate Query Language
15. Criteria Queries
16. Native SQL
Hibernate3 allows you to specify handwritten SQL, including stored procedures, for all create, update, delete, and load operations.
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
More at http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html

Hibernate and stored procedures

As my understanding on setting hibernate, I need to create
table meta data file (person.hbm.xml), include all the fields mapping
java object (person.java)
If we use stored procedures for all transaction, do we still need the above configuration?
It seems hibernate and stored procedures will overlap,
We set up the stored procedure because we don't want the to developer know all the field in db. If tables change, then we need update above files.
Does it mean if we purely use stored procedure, we should just go for JDBC?
If hibernate, we should stay in HQL?
You can use native SQL and map the result to object:
sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
The JDBC syntax to invoke store procedure is like following:
CallableStatement proc =
connection.prepareCall("{ call set_death_age(?, ?) }");
proc.setString(1, poetName);
proc.setInt(2, age);
So maybe, you can invoke stored procedure and map them to object:
sess.createSQLQuery("{ call my_stored_proc }").addEntity(Cat.class);
Note also that updates made through stored procedures will escape hibernate, which means that you will need to evict objects from the 1st level and 2nd level cache yourself.
So as you see, hibernate and stored procedure don't really fit naturally together.
we set up the stored procedure because
we don't want the to developer know
all the field in db. if table change,
then we need update above files.
If you're concerned about security, either use:
database views
Oracle column priviledges
provide mapping files and forbid their modification by developpers
Using Hibenate with Stored Procedures is a certain overlap. As you for example need to write astored procedure for INSERT, UPDATE, DELETE and SELECT, Hibernate provides an easiest way to interract with with relational database objects by mappings them into metadata files like you mentioned person.hbm.xml.
Yes, the use of stored procedure wil require you to write these metadata files anyway. A stored procedure will not replace the Hibernate mappings. Those mapping only tell Hibernate how to persist your object-oriented model to the database. A great thing about Hibernate is that you may even, if needed, generate you database model from your JAVA code through the schema generation tool.
As for the stored procedures, one recommended way is to configure your stored procedures as named queries from within the configuration file. This, however, makes you miss the better potential, in my opinion, of Hibernate.
Does this answer your question? Do you need further explanations?
It is possible to use native-sql and to use stored procedure for querying (with limiations/rules). But, as written in the documentation:
Stored procedures currently only return scalars and entities. <return-join> and <load-collection> are not supported.
So if you want to work with non-managed entities (i.e. not scalars in an Object[]), you'll have to apply a ResultTransformer in the code.
But at the end, if you want to hide the database to developers, if you don't want to map objects to tables, if you don't want to work with associations, if you don't want to use HQL, if you don't want to use an OO approach, then I really wonder why you want to use Hibernate. You'd better use raw JDBC (with Spring for example) or maybe a data-mapper like iBATIS.
You can map the database fields in a result set to an object in hibernate: the documentation explains how.
The idea of Hibernate is to fill the object-relational gap. With the stored procedures (which I can't guess since you haven't told anything about them) you can't get objects from database. You still get rows.
Hiding the database columns from developers sounds like a bad practice to me. Hiding them from the application is perhaps what you want, and you achieve that with the metadata file.

Categories