How to call Oracle function from Hibernate3 [duplicate] - oracle

My question is very much like Getting the return value of a PL/SQL function via Hibernate
I have a function which does some modifications internally and it returns a value.
The original idea was to do something like this:
protected Integer checkXXX(Long id, Long transId)
throws Exception {
final String sql = "SELECT MYSCHEMA.MYFUNC(" + id + ", "
+ transId + ") FROM DUAL";
final BigDecimal nr = (BigDecimal) this.getHibernateTemplate()
.getSessionFactory().getCurrentSession().createSQLQuery(sql)
.uniqueResult();
return nr.intValue();
}
Unfortunately this doesn't work with Oracle. What is the recommended way to do something like this?
Is there a way to extract declared variables from within my statement?

Hibernate Session provides a doWork() method that gives you direct access to java.sql.Connection. You can then create and use java.sql.CallableStatement to execute your function:
session.doWork(new Work() {
public void execute(Connection connection) throws SQLException {
CallableStatement call = connection.prepareCall("{ ? = call MYSCHEMA.MYFUNC(?,?) }");
call.registerOutParameter( 1, Types.INTEGER ); // or whatever it is
call.setLong(2, id);
call.setLong(3, transId);
call.execute();
int result = call.getInt(1); // propagate this back to enclosing class
}
});

You have the following options:
With a #NamedNativeQuery:
#org.hibernate.annotations.NamedNativeQuery(
name = "fn_my_func",
query = "{ ? = call MYSCHEMA.MYFUNC(?, ?) }",
callable = true,
resultClass = Integer.class
)
Integer result = (Integer) entityManager.createNamedQuery("fn_my_func")
.setParameter(1, 1)
.setParameter(2, 1)
.getSingleResult();
With JDBC API:
Session session = entityManager.unwrap( Session.class );
final AtomicReference<Integer> result =
new AtomicReference<>();
session.doWork( connection -> {
try (CallableStatement function = connection
.prepareCall(
"{ ? = call MYSCHEMA.MYFUNC(?, ?) }"
)
) {
function.registerOutParameter( 1, Types.INTEGER );
function.setInt( 2, 1 );
function.setInt( 3, 1 );
function.execute();
result.set( function.getInt( 1 ) );
}
} );
With a native Oracle query:
Integer result = (Integer) entityManager.createNativeQuery(
"SELECT MYSCHEMA.MYFUNC(:postId, :transId) FROM DUAL")
.setParameter("postId", 1)
.setParameter("transId", 1)
.getSingleResult();

Yes, you do need to use an out parameter. If you use the doWork() method, you'd do something like this:
session.doWork(new Work() {
public void execute(Connection conn) {
CallableStatement stmt = conn.prepareCall("? = call <some function name>(?)");
stmt.registerOutParameter(1, OracleTypes.INTEGER);
stmt.setInt(2, <some value>);
stmt.execute();
Integer outputValue = stmt.getInt(1);
// And then you'd do something with this outputValue
}
});

Alternative code :)
if you want to direct result you can use below code
int result = session.doReturningWork(new ReturningWork<Integer>() {
#Override
public Integer execute(Connection connection) throws SQLException {
CallableStatement call = connection.prepareCall("{ ? = call MYSCHEMA.MYFUNC(?,?) }");
call.registerOutParameter( 1, Types.INTEGER ); // or whatever it is
call.setLong(2, id);
call.setLong(3, transId);
call.execute();
return call.getInt(1); // propagate this back to enclosing class
}
});
http://keyurj.blogspot.com.tr/2012/12/dowork-in-hibernate.html

public static void getThroHibConnTest() throws Exception {
logger.debug("UsersActiion.getThroHibConnTest() | BEG ");
Transaction tx = null;
Connection conn = null;
CallableStatement cs = null;
Session session = HibernateUtil.getInstance().getCurrentSession();
try {
tx = session.beginTransaction();
conn = session.connection();
System.out.println("Connection = "+conn);
if (cs == null)
{
cs =
conn.prepareCall("{ ?=call P_TEST.FN_GETSUM(?,?) }");
}
cs.clearParameters();
cs.registerOutParameter(1,OracleTypes.INTEGER);
cs.setInt(2,1);
cs.setInt(3,2);
cs.execute();
int retInt=cs.getInt(1);
tx.commit();
}catch (Exception ex) {
logger.error("UsersActiion.getThroHibConnTest() | ERROR | " , ex);
if (tx != null && tx.isActive()) {
try {
// Second try catch as the rollback could fail as well
tx.rollback();
} catch (HibernateException e1) {
logger.debug("Error rolling back transaction");
}
// throw again the first exception
throw ex;
}
}finally{
try {
if (cs != null) {
cs.close();
cs = null;
}
if(conn!=null)conn.close();
} catch (Exception ex){;}
}
logger.debug("UsersActiion.getThroHibConnTest() | END ");
}

Related

ResultSet doesn't return values for DB2, but it return values if I try to do it manualy

I'm trying to get values from resulset, but it return nothing.
When i'm trying to do it through plain sql it return some values.
List<String> res = new ArrayList<String>();
try {
String query = "SELECT COLUMN_NAME FROM idoc.columns_to_show where user = ? "
+ DAO.DB2_UR_POSTFIX;
Connection connection = Properties.getDocsConnection();
try {
PreparedStatement pr = connection.prepareStatement(query);
try {
pr.setString(1, user.getDomainName());
ResultSet rs = pr.executeQuery();
try {
while (rs.next()) {
res.add(rs.getString("COLUMN_NAME"));
}
} finally {
rs.close();
}
} finally {
pr.close();
}
} finally {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return res;
Don't use column name "user" it is reserved name for DB2 database.
Therefore I couldn't find any result.

Getting oracle table row lock, from application

I am getting oracle table row lock, while using below mentioned method written in DAOImpl only in production server. Its working fine in testing server.
`public boolean inactiveServices(String custUid) {
Session session = null;
try {
session = sessionFactory.openSession();
Long count = (Long) (session.createQuery(
"select count(*) as intcustomeridpk from CustomerRegistrationPOJO t where t.customerRegistrationPK.custUid = '"
+ custUid + "'").iterate().next());
if (count < 1)
return false;
String queryToFetchUserIdPk = "select t.customerRegistrationPK.intCustomerId as intcustomeridpk from CustomerRegistrationPOJO t where t.customerRegistrationPK.custUid = '"
+ custUid + "'";
//Iterator iterator = session.createQuery(queryToFetchUserIdPk).iterate();
String currentCustIntIdPk = (String) session.createQuery(queryToFetchUserIdPk).iterate().next();
System.out.println("currentCustIntIdPk "+currentCustIntIdPk);
Criteria criteria = session.createCriteria(CustUtilsPOJO.class).add(
Restrictions.eq("custUtlilityKey.custUid", currentCustIntIdPk))
.add(Restrictions.eq("ynActive", "Y"))
.add(Restrictions.ne("dmlFlag", 2));
List<CustUtilsPOJO> foundUtilList = criteria.list();
for (CustUtilsPOJO eachUtil : foundUtilList) {
System.out.println("centerCode=="+eachUtil.getCenterCode()+"serviceId=="+eachUtil.getCustUtlilityKey().getUtilNumber()+"utilityId=="+eachUtil.getCustUtlilityKey().getUtilId()+"intCustUtil=="+eachUtil.getIntCustomerUtlServiceId());
eachUtil.setDmlFlag(2);
eachUtil.setYnActive("N");
session.merge(eachUtil);
}
Transaction txn = session.beginTransaction();
txn.commit();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (session != null && session.isOpen()) {
session.flush();
session.clear();
session.close();
}
}
return true;
}`

In phoenix for hbase , upsert OOM when insert 90000 row data

Run cmd :
./jsvc64/jsvc64 -pidfile ./log/jsvc.pid -outfile ./log/out.txt -errfile ./log/error.txt -Xmx512m -Djava.util.Arrays.useLegacyMergeSort=true -cp :./tools/lib/:./tools/ com.g2us.hbase.cmdlog.monitor.CmdLogHbase ./
SQL :
UPSERT INTO CMDLOG_20130818(game,roleid,otime,logtype,passport,subgame,cmdid,exception,moreinfo,pname_0,pname_1,pname_2) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)
upsert 90000 row data,the exception occored.
How to solve it.
Exception in thread "Thread-0" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.reflect.Method.copy(Method.java:143)
at java.lang.reflect.ReflectAccess.copyMethod(ReflectAccess.java:118)
at sun.reflect.ReflectionFactory.copyMethod(ReflectionFactory.java:282)
at java.lang.Class.copyMethods(Class.java:2748)
at java.lang.Class.getMethods(Class.java:1410)
at org.apache.hadoop.hbase.ipc.Invocation.<init>(Invocation.java:67)
at org.apache.hadoop.hbase.ipc.WritableRpcEngine$Invoker.invoke(WritableRpcEngine.java:86)
at $Proxy8.getClosestRowBefore(Unknown Source)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegionInMeta(HConnectionManager.java:1019)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegion(HConnectionManager.java:885)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegion(HConnectionManager.java:846)
at org.apache.hadoop.hbase.client.HTable.finishSetup(HTable.java:271)
at org.apache.hadoop.hbase.client.HTable.<init>(HTable.java:211)
at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:160)
at org.apache.hadoop.hbase.client.MetaScanner.access$000(MetaScanner.java:54)
at org.apache.hadoop.hbase.client.MetaScanner$1.connect(MetaScanner.java:133)
at org.apache.hadoop.hbase.client.MetaScanner$1.connect(MetaScanner.java:130)
at org.apache.hadoop.hbase.client.HConnectionManager.execute(HConnectionManager.java:383)
at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:130)
at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:105)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.prefetchRegionCache(HConnectionManager.java:947)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegionInMeta(HConnectionManager.java:1002)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegion(HConnectionManager.java:889)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.locateRegion(HConnectionManager.java:846)
at org.apache.hadoop.hbase.client.HTable.finishSetup(HTable.java:271)
at org.apache.hadoop.hbase.client.HTable.<init>(HTable.java:263)
at com.salesforce.phoenix.query.HTableFactory$HTableFactoryImpl.getTable(HTableFactory.java:60)
at com.salesforce.phoenix.query.ConnectionQueryServicesImpl.getTable(ConnectionQueryServicesImpl.java:133)
at com.salesforce.phoenix.execute.MutationState.commit(MutationState.java:227)
at com.salesforce.phoenix.jdbc.PhoenixConnection.commit(PhoenixConnection.java:244)
at com.g2us.hbase.phoenix.HBaseHelper.executeUpdate(HBaseHelper.java:62)
at com.g2us.hbase.cmdlog.io.BaseLogPoster.upsertRow(BaseLogPoster.java:153)
I found the problem and fixed it.
the problem that 's preStat define as class field var ,so that call executeQuery() many time no close it ,then OutOfMemoryError.
error code:
public class F{
PreparedStatement preStat = null;
public ResultSet executeQuery(String sql, Object... args) throws Exception {
ResultSet rsResultSet = null;
Connection conn = null;
Statement stat = null;
try {
conn = HBaseUtility.getConnection();
preStat = conn.prepareStatement(sql);
if (args != null) {
for (int i = 0; i < args.length; i++) {
preStat.setObject(i + 1, args[i]);
}
}
rsResultSet = preStat.executeQuery();
} catch (Exception e) {
dispos(conn, stat);
Log.error(Log.DB, "queryerror|", e);
throw new RuntimeException("hbase query error");
} finally {
HBaseUtility.release(conn);
}
return rsResultSet;
}
}
fixed code:
public class F{
public ResultSet executeQuery(String sql, Object... args) throws Exception {
ResultSet rsResultSet = null;
Connection conn = null;
Statement stat = null;
try {
PreparedStatement preStat = null; //this var as a class var ,and no close every query .
conn = HBaseUtility.getConnection();
preStat = conn.prepareStatement(sql);
if (args != null) {
for (int i = 0; i < args.length; i++) {
preStat.setObject(i + 1, args[i]);
}
}
rsResultSet = preStat.executeQuery();
preStat.close(); //must be close.
} catch (Exception e) {
dispos(conn, stat);
Log.error(Log.DB, "queryerror|", e);
throw new RuntimeException("hbase query error");
} finally {
HBaseUtility.release(conn);
}
return rsResultSet;
}
}

-> java.sql.SQLException: Exhausted Resultset

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
if (evt.getSource() == jButton1) {
String ab = jTextField1.getText();
String bc = jPasswordField1.getText().toString();
String cd = jTextField2.getText();
String de = jTextField3.getText();
PreparedStatement ps1 = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection c = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe", "system", "hr");
ps = c.prepareStatement("Select User_Name from AdminLogin where Password =?");
ps.setString(1, bc);
rs = ps.executeQuery();
rs.next();
if (ab.equals(rs.getString(1))) {
ps1 = c.prepareStatement("Update AdminLogin SET Date1=?,Time=? WHERE Password=?");
ps1.setString(1, cd);
ps1.setString(2, de);
ps1.setString(3, bc);
int e = ps1.executeUpdate();
JOptionPane.showMessageDialog(this, "Welcome", "Logged In", JOptionPane.INFORMATION_MESSAGE);
//MainMenuAAI mainMenuAAI = new MainMenuAAI();
//setVisible(false);}
} else if (!(ab.equals(rs.getString(1)))) {
JOptionPane.showMessageDialog(this, "<html>YOU ARE NOT A<br>ADMIN</br></html>", "ERROR", JOptionPane.ERROR_MESSAGE);
//AdminLogin admin=new AdminLogin();
//setVisible(false);
}
c.close();
} catch (Exception e) {
System.out.println(e);
}
}// TODO add your handling code here:
}
Everything is working fine in the code. It is executing the code inside
if(ab.equals(rs.getString(1)))
and showing "Welcome" but not d one inside
if(!(ab.equals(rs.getString(1))))
Whenever I enter wrong username or password it shows the error
java.sql.SQLException: Exhausted Resultset
That is correct, because if you enter wrong username or password, NO record will be returned. So, when you use the rs.next(); in this case, it is trying to access the first row of the empty result set! And that is where it is throwing the exception.
You could fix your code like this:
rs = ps.executeQuery();
//rs.next();
int counter=0;
while (rs.next()) {
counter++;
if (ab.equals(rs.getString(1))) {
ps1 = c.prepareStatement("Update AdminLogin SET Date1=?,Time=? WHERE Password=?");
ps1.setString(1, cd);
ps1.setString(2, de);
ps1.setString(3, bc);
int e = ps1.executeUpdate();
JOptionPane.showMessageDialog(this, "Welcome", "Logged In", JOptionPane.INFORMATION_MESSAGE);
//MainMenuAAI mainMenuAAI = new MainMenuAAI();
//setVisible(false);}
}
}
if(counter==0){
JOptionPane.showMessageDialog(this, "<html>YOU ARE NOT A<br>ADMIN</br></html>", "ERROR", JOptionPane.ERROR_MESSAGE);
}

preparedStatement.setNull(int parameterIndex, int sqlType)

Question #1
Could you anyone please tell me what is the benefit I will receive using the following code, when sPhoneExt is null ?
if (sPhoneExt == null || sPhoneExt.trim().equals("")) {
stmt.setNull(9, java.sql.Types.INTEGER);
} else {
stmt.setString(9, sPhoneExt);
}
Instead of stmt.setString(9, sPhoneExt);
Because iPhoneType = rset.getInt("phone_type"); will return 0 if the value is SQL NULL; which I don't want.
Question #2
And just curious stmt.setString(9, null) is performed what will be the return of rset.getInt("phone_type")?
Answer #2
getInt() will return zero when it is null in DB. You have to use the below code to know about DB NULL.
if (rs.wasNull()) {
// handle NULL field value
}
I don't see any benefit using setNull in this String case.
It is only used to check empty string "" and insert null in DB. But for that also we can do it like stmt.setString(9, null);
But when sPhoneExt is Integer and holding null, then We cannot perform
stmt.setInt(9, sPhoneExt); since setInt(int, int) API performs; converting (Unboxing) sPhoneExt (Integer) to primitive (int), so you will get NullPointerException. So you are in need of stmt.setNull(9, java.sql.Types.INTEGER);
Finally if you have inserted null in DB for NUMBER (sql type) column; getInt() will return 0 only.
This is irrespective of the below null set mechanism.
stmt.setString(9, null);
stmt.setNull(9, java.sql.Types.INTEGER)
Also Somebody told when the DB NUMBER column has default Value; that default value will be consider differently by the above two lines. But that is not true. Even that case also both the above line performs same way. It is setting NULL value; not the default value.
create table t1 (id number default 1 );
insert into t1 (id) values (2);
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class TestDB {
public static void main(String args[]) {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection con = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:#10.201.32.92:1521:psprd1", "username", "password");
String query = null;
String l = null;
ResultSet rset = null;
int paramIndex = 1;
query = "UPDATE t1 " + " SET id = ?";
stmt = con.prepareStatement(query);
stmt.setInt(paramIndex++, null);
// stmt.setNull(1, java.sql.Types.INTEGER);
stmt.executeUpdate();
stmt.close();
query = "select id from t1 ";
stmt = con.prepareStatement(query);
rset = stmt.executeQuery();
rset.next();
System.out.println(rset.getString("id"));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
rs.close();
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

Resources