Get all Tables in a Db using hibernate - java

Is there a way to retrieve the name of all tables in the database using hibernate?
I executed the query SELECT TABLE_NAME FROM USER_TABLES in an oracle Db and it works just fine.
But when it comes to DB2, it wont.

You can use
List<Object> list = session.createQuery("from java.lang.Object").list();
This will return all persistent entities (thanks to HQL implicit polymorphism), and this is db independent. Note that it will exclude tables with no records.
If you need all tables, including the empty ones, you can use native sql query
List<Object[]> list = session.createSQLQuery("select * from sysibm.systables").list();
The drawback for the native query is that it is specific for each database, for example, on Oracle the query is "select * from user_tables".

Related

fetching single column values in JPA

I want to get all the values from a particular column in JPA and store all values into a list. currently, I am using the below approach but I am getting records in something else format.can someone please help me out
Query q1 = factory.createNativeQuery("select * from booking_attendee where booking_id="+id);
List<String> em1=q1.getResultList();
return em1;
query otput
em=[[Ljava.lang.Object;#68606667, [Ljava.lang.Object;#2cd7f99a, [Ljava.lang.Object;#137a5a5, [Ljava.lang.Object;#a45cc1c, [Ljava.lang.Object;#61fdc06d, [Ljava.lang.Object;#72f5eee1, [Ljava.lang.Object;#4e536797]
If you want to create a native query for this, it is more about how to solve this in SQL. You do not say SELECT * which means all columns. You would have to say SELECT your_column_name to select only a specific column.
Query q1 = factory.createNativeQuery("SELECT your_column FROM booking_attendee");
List<String> em1 = q1.getResultList();
The WHERE clause could and should be defined with the parameter binding of JPA. There are several advantages concerning performance and SQL injection.
Named parameter binding is special to the persistence provider (e.g. Hibernate). The common way for JPA is using ? to let your code be portable to other providers.
Query q1 = factory.createNativeQuery("SELECT your_column FROM booking_attendee b WHERE b.booking_id = ?");
q1.setParameter(1, id);
List<String> em1 = q1.getResultList();
Native queries offer the possibilities to use original SQL. Like this, some features which are specific for your database could be used with this. Nevertheless, if you do not have very specific SQL code, you should also have a look in JPQL, the specific query language of JPA, and the JPA Criteria API which offers advantages when you want to refactor your code, shows errors during compile time and makes the dynamic creation of queries easier.

How to perform some operation based on SQL return code I am using spring data JPA

I am working on some project where I used spring data jpa to query against DB2. Suppose used query "Select a,b from sometable where a='XX' ". So now based on sql code I want to perform some operation but how I will get sql return code as I am using spring data JPA.
Thanks in advance

How to use 'Insert' in a nativeSQL query in Hibernate outside the mapped class ?

In Hibernate, you can use the 'SELECT' queries in native SQL like this :
Query query = session.createSQLQuery("SELECT ... FROM ...");
But I would want to use an 'INSERT' query.
So, I looked at the documentation, and it seems you must go directly to the mapped class and write the code inside it.
But I would want to use it as I do for a 'SELECT' query (outside the mapped class) since it looks much more pratical.
Indeed, why would the treatment be different between 'SELECT' and 'INSERT' for a hibernate native SQL query ?
An HQL INSERT cannot be used to directly insert arbitrary entities—it can only be used to insert entities constructed from information obtained from SELECT queries (unlike ordinary SQL, in which an INSERT command can be used to insert arbitrary data into a table, as well as insert values selected from other tables).
Here’s the syntax of the INSERT statement:
INSERT INTO path ( property [, ...]) select
The name of an entity is path. The property names are the names of properties of entities listed in the FROM path of the incorporated SELECT query. The select query is an HQL SELECT query (as described in the next section).
As this HQL statement can only use data provided by an HQL select, its application can be limited. An example of copying users to a purged table before actually purging them might look like this:
Query query=session.createQuery("insert into purged_accounts(id, code, status) "+
"select id, code, status from acount where status=:status");
query.setString("status", "purged");
int rowsCopied=query.executeUpdate();
Or you can use
session.persist(obj);
where obj is the object of the POJO class let say TestClass
TestClass obj=new TestClass('','',''); //paramatrized constructor for the values you want to insert in your database.

Left join on unrelated tables in Query DSL and JPA

I have two unrelated tables, each one with field email. I need a query which introduces column taken from second table if emails match or will be null if no match is found. In SQL this is easy:
SELECT tableA.id, tableA.email, tableB.name
FROM tableA
LEFT JOIN tableB ON tableA.email=tableB.email
ORDER BY tableB.name
Unfortunately JPA doesn't allow joins over unrelated entities so I converted it to:
SELECT tableA.id, tableA.email,
(SELECT tableB.name FROM tableB WHERE tableB.email=tableA.email) AS aname
FROM tableA
ORDER BY aname
Now, it works as JPA query but we are using Query DSL so off we go to converting it:
JPQLQuery query = new JPAQuery(em);
List<Dto> items=query.from(qTableA)
.list(new QDto(qTableA.id, qTableA.email,
new JPASubQuery().from(qTableB)
.where(qTableB.email.eq(qTableA.email)).unique(qTableB.name)))
It works but now I have no idea how to implement sorting and filtering by field introduced by subquery.
Dto is a POJO used to collect results, QDto is a class autogenerated from Dto.
Question is: how to join two unrelated tables using Query DSL and JPA and avoiding native SQL? Is it possible? Sorting and filtering on fields from tableA and tableB.name is a requirement.
Join on unrelated entities is not covered by latest JPA spec (2.1)
However Hibernate 5.1.0+ and EclipseLink 2.4.0+ support ad hoc joins. http://blog.anthavio.net/2016/03/join-unrelated-entities-in-jpa.html

can do this with JPA / Hibernate

I am working with postgres and using JPA with Hibernate, in postgres and other DBMS can do this:
SELECT *, function(parameter) AS xyz FROM table WHERE condition
My question is this, the query can display an additional field (xyz), although there is no such column. I can do that with Hibernate JPA.
If you don't have a mapped entity then you will need to use native queries:
Query query = entityManager
.createQuery(
"SELECT t.*, myfunction(:parameter) FROM table t WHERE t.attr = condition");
query.setParameter("parameter", value);
List resultList = query.getResultList();
Otherwise, if you have a mapped entity you can do this with typed queries or the criteria API.
With typed queries:
TypedQuery<Object[]> query = entityManager
.createQuery(
"SELECT t.*, FUNC('MyFunction', :parameter) FROM table t WHERE t.attr = condition",
Object[].class);
query.setParameter("parameter", value);
List<Object[]> resultList = query.getResultList();
With criteria API:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> query = criteriaBuilder.createTupleQuery();
Root<Table> root = query.from(Table.class);
Expression<Long> funcExpr = criteriaBuilder.function("myfunction",
Long.class, root.get("parameter"));
query.multiselect(query.select(root), funcExpr);
List<Tuple> resultList = entityManager.createQuery(query)
.getResultList();
By using org.hibernate.SQLQuery, you can create native SQL queries with Hibernate. You then execute these queries the same way you would with a normal Hibernate query. Obviously you're going to lose many of the benefits of letting Hibernate and JPA manage your queries, but if they do not support the feature you want, it may be the only way to do it.
Another solution is to use Formulas, if you invoke your function on some fields of the table, and you always want the result of the function you can map another property in your entity and annotate it with #Formula("myFunction(field1, field2)"). Hibernate will add this to all of your queries which have your entity.

Categories