Execute Normal SQL Query in Hibernate - java

I'm using Hibernate for Database connection. My user has the right to get the open_mode (select open_mode from v$database).
I wanted to execute the query in hibernate using the existing hibernate DB configuration Also I do not want to create a JDBC connection codes in my java file like the below
String url = "jdbc:oracle:thin:#192.179.9.31:1521:db1";
Connection conn = DriverManager.getConnection(url,"user","password");
Statement stmt = conn.createStatement();
ResultSet rs;
rs = stmt.executeQuery("select openmode from v$database");
while ( rs.next() ) {
String lastName = rs.getString("openmode");
Since this v$database is not a real table in our schema, I am thinking we cannot create a entity class for v$database and execute the query using hql.
Anyone how I can execute the above query and get a result using my existing config.
Here is my hibernate configuration detail.
<property name="dialect"> org.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.url"> jdbc:oracle:thin:#192.179.9.31:1521:db1
</property>
<property name="connection.username">user</property>
<property name="connection.password">passsword</property>
<property name="connection.driver_class"> oracle.jdbc.driver.OracleDriver
</property>
<property name="myeclipse.connection.profile"> Oracle 9i Connector
</property>

You can create native queries in Hibernate for tables which don't have mapped entities.
Create a hibernate session as you do generally and then create native query referring below snippet.
String sqlQuery = "select openmode from v$database";
Query q = session.createNativeQuery(sqlQuery);
List<Object[]> listResults = query.getResultList();
This will return list of arrays. You need to iterate over this list and parse the output to any POJO in your domain.
An example is provided on this page.
You can also used overloaded version of this method for entities mapped with tables to take benefit of DB specific features such as hints or CONNECT BY.
Update
Another way which OP tried was to use createSQLQuery. Scalar is used to map the columns with Hibernate type.
String sqlQuery = "select open_mode from v$database";
SQLQuery query = session.createSQLQuery(sqlQuery).addScalar("open_mode", Hibernate.STRING);
List result = q.list();
String open_mode = result.get(0).toString();

You could use session.doWork(...) method.
This is meant for allowing users to perform JDBC related work using the Connection managed by this Session.
session.doWork(new Work() {
#Override
public void execute(Connection connection) throws SQLException {
//Perform JDBC statement, resultset etc here.
}
});

Related

Get specific columns of table in hibernate using addEntity

I am familiar with Java but really new with ORM and Hibernate.
I am using the following query to get the resultset of all columns of a table in hibernate.
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").addEntity(Neighborhood.class).list();
I want to get only two specific column from this table. I looked up over the internet but not able to find the solution which can be used as a modification of above statement.
I tried the below query but getting - SQLGrammarException: could not extract ResultSet
(List<Neighborhood>)session.createSQLQuery("SELECT neighborhoodName,educationYouth FROM Neighborhood").addEntity(Neighborhood.class).list();
Edit:
Two more attempted queries after #scaryWombat's suggestion. Both give the same exception
First
List list = session.createSQLQuery("SELECT neighborhoodName,educationYouth FROM Neighborhood").list();
Second
String sql = "SELECT neighborhoodName,educationYouth FROM Neighborhood";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();
Edit2:
After #Tehmina's solution, I am getting one error - java.sql.SQLException: Column 'educationYouth' not found because educationYouth is an object of class name "EducationYouth".
In the Neighborhood table there is no column with name educationYouth but all the column from EducationYouth class.
Try this
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").list();
To avoid the overhead of using ResultSetMetadata, or simply to be more explicit in what is returned, one can use addScalar():
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").addScalar("neighborhoodName", Hibernate.STRING).addScalar("educationYouth", Hibernate.STRING);
Or try this
Hibernate automatically converts the data into appropriate type. The automatic conversion does not work in all cases and in that case we have an overloaded version of addScalar():
SQLQuery q = session.createSQLQuery("SELECT * FROM Neighborhood");
q.addScalar("neighborhoodName");
q.addScalar("educationYouth");
List<Object[]> rows = q.list();
for (Object[] row : rows) {
System.out.println(row[0] + " " + row[1] );
Don't forget to check in the hibernate config file
<!--hibernate.cfg.xml -->
<property name="show_sql">true</property>
I hope it would resolve your error.

Can JDBC return a domain object as query result

I have a table user in a MySQL database, and I created a class User for my project. I would like to get the record directly in a User object as in Hibernate, without using Hibernate:
User u = (User) session.get(User.class, id);
I use a JDBC driver.
Is there any way to get a result set as Object like:
Statement stmt = db.createStatement();
User u = stmt.executeQuery("SELECT * FROM user",User.class);
I am a lazy programmer, I wouldn't create a list, create a loop to iterate it and set all variables.
I've solved.
#Kayaman I've found ORMlite library.
String databaseUrl = "...";
ConnectionSource cs = new JdbcConnectionSource(databaseUrl);
Dao<User,Integer> userDAO = DaoManager.createDao(cs, User.class);
User u = userDAO.queryForId(1);
System.out.println(u.getName());
For http://ormlite.com/javadoc/ormlite-core/doc-files/ormlite_1.html#Getting-Started
Short answer: No.
What you are asking for is called an ORM. JDBC is not an ORM. Hibernate is an ORM for Java, which uses JDBC to actually connect to and interact with the database server. EclipseLink is another Java ORM (it is the one included with glassfish).

How to get all trigger names from a database using Java JDBC?

I'd like to retrieve all trigger names from an Oracle database schema.
I use getFunctions to retrieve all functions but i can't find another one for the triggers.
DatabaseMetaData dbmd;
ResultSet result = dbmd.getFunctions(null, Ousername, null);
You can do it using metadata.
DatabaseMetaData dbmd = dbConnection.getMetaData();
ResultSet result = dbmd.getTables("%", Ousername, "%", new String[]{ "TRIGGER" });
while (result.next()) {
result.getString("TABLE_NAME")
}
The JDBC API does not provide a standard way to retrieve trigger information from the DatabaseMetaData. In fact, the word "trigger" does not even appear in the Javadoc. The accepted answer may work for Oracle, but it is not documented, and it certainly does not work for other databases like HSQL and PostgreSQL.
The only way, at this time, to retrieve trigger information without finding some undocumented backdoor hack in the JDBC driver is to issue database specific queries.
I have found another way to get all trigger via PreparedStatement:
try {
System.out.println("\n******* Table Name: "+ tableName);
String selectQuery = "SELECT TRIGGER_NAME FROM ALL_TRIGGERS WHERE TABLE_NAME = ?";
PreparedStatement statement = DataSource.getConnection().prepareStatement(selectQuery);
statement.setString(1, tableName.toUpperCase());
ResultSet result = statement.executeQuery();
System.out.println("Triggers: ");
while (result.next()) {
String triggerName = result.getString("TRIGGER_NAME");
System.out.println(triggerName);
}
} catch (SQLException e) {
e.printStackTrace();
}
Just hint for MySQL users: if you want to retrieve all triggers from MySQL database there is table TRIGGERS in INFORMATION_SCHEMA with all info about database triggers:
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
Similar is for routines (Functions and Procedures)
SELECT * FROM INFORMATION_SCHEMA.ROUTINES
Unfortunately triggers are not well supported in JDBC MetaData.

Hibernate dialect

I am using Hibernate to accessing data from sql server 2008.while executing the following code
Session session = sessionFactory.openSession();
String qry="select Form_Id,SUBSTRING(
(SELECT ( '' + t2.Form_Layout_Txt) FROM Form_Layout_Info t2
WHERE t1.Form_Id = t2.Form_Id " +
" GROUP BY Form_Layout_Txt FOR XML path('') ), 1,1000000000)
FROM Form_Layout_Info t1 GROUP BY Form_Id";
SQLQuery query = session.createSQLQuery(qry);
recordList = query.list();
My Hibernate properties is
hibernate.connection.driver_class=com.microsoft.sqlserver.jdbc.SQLServerDriver
hibernate.connection.url=jdbc:sqlserver://localhost:1433;databaseName=abc;integratedSecurity=false;
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.connection.username=sa
hibernate.connection.password=p123asc
i received the following error
No Dialect mapping for JDBC type: -9
How to fix the issue.
You need to provide hibernate.dialect=org.hibernate.dialect.SQLServerDialect in configuration for sql server.
Either provide it in hibernate.cfg.xml as :
<hibernate-configuration>
<session-factory name="session-factory">
.....
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
....
</session-factory>
</hibernate-configuration>
or in properties file as :
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
I don't know which way you are using, so posted both I know.
I found 2 solutions for your problem here:
try changing your driver to jTDS
using the ms sql server jdbc driver provided by microsoft can cause this issue while jTDS does not give this complaint.
you may need to explicitly “addScalar” to your hibernate query. You might have something like this:
sess.createSQLQuery("SELECT * FROM CATS");
// try changing to:
sess.createSQLQuery("SELECT * FROM CATS")
.addScalar("ID", Hibernate.LONG)
.addScalar("NAME", Hibernate.STRING)
.addScalar("BIRTHDATE", Hibernate.DATE)
This issue is related to type mapping done while returning data. And mapping for that particular data type not exists in Dialect.
https://forum.hibernate.org/viewtopic.php?f=1&t=959583
Hibernate Data types -
http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/type/StandardBasicTypes.html
The error means hibernate doesn’t know how to map the JDBC type “NVARCHAR” to a hibernate type.
Solution 1:
Using addScalar like this:
Session session = sessionFactory.openSession();
String qry="select Form_Id,SUBSTRING(
(SELECT ( '' + t2.Form_Layout_Txt) as formLayoutTxt FROM Form_Layout_Info t2
WHERE t1.Form_Id = t2.Form_Id " +
" GROUP BY Form_Layout_Txt FOR XML path('') ), 1,1000000000)
FROM Form_Layout_Info t1 GROUP BY Form_Id";
SQLQuery query = session.createSQLQuery(qry).addScalar("formLayoutTxt", StringType.INSTANCE);
recordList = query.list();
Solution 2: Register the Hibernate Type in Dialect
public class MySQLServerDialect extends SQLServerDialect {
public MySQLServerDialect() {
super();
// Register mappings
registerHibernateType(Types.NVARCHAR, StringType.INSTANCE.getName());
}
}
For more details, check out this.

Hibernate update not working

I am new with hibernate and I was trying to update a mapped object with the following code, but it does not update
factory = config.buildSessionFactory();
session = factory.getCurrentSession();
Transaction t = session.beginTransaction();
String hql = "UPDATE "+tableName+" SET "+columnName+" = '"+columnValue+"' WHERE id ="+id+";";
Query query=session.createSQLQuery(hql);
t.commit();
Am I missing something? It do not crash nor update the record.
NOTE: I am using Hibernate3 and Mysql
You're missing query.executeUpdate();
Also, if you're updating a mapped object I would recommend you to make the changes to the java object, and let Hibernate do the update for you. Or at least use a hql query, not a native one.
Make sure that your persistence.xml file has show_sql set to true and watch the log to see if the update is executed.
<property name="hibernate.show_sql" value="true"/>
You need to use query.executeUpdate() to run the query.
Also it is suggested that you use parameters instead of inline arguments. For eg. if the columnName = O'Reilly then the whole query will go wrong.
Also if it is a mapped object you can use HQL rather than SQL query
Instead you can use this
//entity is your hibernate entity obj
String hql = "UPDATE " + entity.getClass().getName + " as entity SET entity." + fieldName + "= :columnValue WHERE entity = :entity";
Query query=session.createQuery(hql).setParameter("columnValue", columnValue).setParameter("entity", entity);
query.executeUpdate();
Notice that you don't need to use single quotes. setParameter handles it.

Categories

Resources