Hibernate - Traversing createSQLQuery results and reading into appropriate object - java

I am pretty new to Hibernate / Java (JSF 2.0) and I am attempting to call a custom query and read the results into an object that I have created Logins. Logins has two setter functions, setLoginDate(Date date) and setUserId(Integer userId) my function looks like so, The issue I am having is how to transform the result set and read in the appropriate values into a temp loginList
public List<Logins> getUserLogins() {
Session session = getSessionFactory().openSession();
List<Logins> loginList = null;
Login temp = null;
try {
String SQL_QUERY = "SELECT login_date, user_id FROM user_logins";
Query query = session.createSQLQuery(SQL_QUERY);
List results = query.list();
for(ListIterator iter = results.listIterator(); iter.hasNext(); ) {
** THIS IS THE PART I AM NOT CLEAR ON ***
temp.setLoginDate(resutls.get(0));
temp.setUserId(results.get(1));
loginList.add(temp);
temp = null;
*****************************************
return loginList;
}
} catch(HibernateException e) {
throw new PersistanceDaoException(e);
} finally {
session.close();
}
}

missing part:
Object[] row = (Object[]) iter.next();
temp = new Login();
temp.setLoginDate(row[0]);
temp.setUserId(row[1]);
you may need to cast row[i] to your target object for example if login date is a date object: temp.setLoginDate((Date) row[0]);

for a better solution, try to use ResultTransformer
you can find more about ResultTransformer in Hibernate Docs.

Related

How to retrieve a key from a Hashtable in Java

I'm a newbie in Java and I'm trying to find a way to retrieve a key from Hashtable. The code below was written to retrieve values from in a database and insert in Hashtable in key/value pair format using a stored procedure.
private Hashtable loadRspCodeMappingFromDB(String node_name)
throws SQLException
{
//TO DO:
// Take a look at the SDK user guide -> Programming conventions -> Database access using JDBC.
// Use the stored procedure you've created to fill a Hashtable to return.
// Two events have been created in events.er for your use:
// RspCodeMappingLoaded, and
// ErrorReadingRspCodeMapping
Hashtable resp_mapping_table = new Hashtable();
Connection cn = null;
CallableStatement stmt = null;
ResultSet rs = null;
try
{
cn = JdbcManager.getDefaultConnection();
stmt = cn.prepareCall("{call samplenid_get_rsp_map(?)}");
stmt.setString(1, node_name);
rs = stmt.executeQuery();
while(rs.next()){
tm_rsp_code = rs.getString(1);
Interchange_rsp_code = rs.getString(2);
resp_mapping_table.put(tm_rsp_code, Interchange_rsp_code);
}
JdbcManager.commit(cn, stmt, rs);
}
finally
{
JdbcManager.cleanup(cn, stmt, rs);
}
return resp_mapping_table;
}
The second code block is written to retrieve the mapped key from a Hashtable and include in a transaction message, but unfornately I'm getting this error: "cannot convert from element type Object to Map.Entry.
public Action processMsgFromRemote(AIntegrationDriverEnvironment env,Iso8583Post msg)
throws XPostilion, SQLException
{
//TO DO:
// 1. Check if the message is a response message
// 2.1 Check the integration driver environment to discover the sink node name
// 2.2 If the rsp code mapping has not yet been loaded, load rsp code
// mapping from table now. Use the loadRspCodeMappingFromDB() method
// below.
// 3.1 Check if a mapping exists
// 3.2 If a mapping exists, set the value to transaction manager
// 4. Return the action with the message to Transaction Manager
Action action = new Action();
boolean check_msg_type = Iso8583Post.MsgType.isResponse(msg.getMsgType());
if(check_msg_type){
String node_name = env.getSinkNodeName();
if( rsp_map == null)
{
rsp_map = loadRspCodeMappingFromDB(node_name);
}
else{
String rsp_code_from_cache_loader = (String) rsp_map.get(tm_rsp_code);
String rsp_code_msg_from_interchange = msg.getField(Iso8583.Bit._039_RSP_CODE);
if(rsp_code_from_cache_loader.equals(rsp_code_msg_from_interchange)){
for(Map.Entry entry: rsp_map.entrySet()){
if(rsp_code_from_cache_loader.equals(entry.getValue())){
tm_rsp_code = (String) entry.getKey();
break;
}
}
}
}
}
action.putMsgToTranmgr(msg);
return action;
}
I would like to know what would be the solution to this error. How should I fix it ?

oracleConnection.createARRAY not working with WebLogic Data Source Connection

So, I was using a datasource which was defined in Spring, which was working fine. Then I updated my project to take the datasource from the Weblogic server which the application is running on. This too, works fine for most calls to the database, except for one scenario - This scenario is involved sending a list of objects to the database, based on database types which are defined in Java by using Structs.
The full method is:
#Override
public List<String> saveAllocation(String originalId, List<Parcel> parcels) throws SQLException {
if(originalId == null || parcels == null) {
return null;
}
List<String> results = null;
String result = null;
String log = null;
OracleConnection oracleConnection = (OracleConnection)jdbcTemplate.getDataSource().getConnection();
try {
OracleCallableStatement cs = (OracleCallableStatement) oracleConnection.prepareCall("{ call PACKAGE.Update(?, ?, ?, ?) }");
Struct[] cpoList = new Struct[parcels.size()];
for(int i = 0; i < parcels.size(); i++) {
Object[] obj = new Object[] { parcels.get(i).getParcel_id(), parcels.get(i).getPublicID().toUpperCase() };
Struct struct = oracleConnection.createStruct("SCHEME_NAME.PARCEL_OBJ", obj);
cpoList[i] = struct;
}
Array array = oracleConnection.createARRAY("SCHEME_NAME.PARCEL_TAB", cpoList);
cs.setString(1, originalId);
cs.setArray(2, array);
cs.registerOutParameter(3, Types.VARCHAR);
cs.registerOutParameter(4, Types.VARCHAR);
cs.executeUpdate();
log = cs.getObject(3).toString();
result = cs.getObject(4).toString();
results = new ArrayList<>();
results.add(result);
results.add(log);
} catch(SQLException e) {
//Log exception
return results;
} catch(Exception e) {
//Log exception
return results;
} finally {
if (cs != null) {
cs.close();
}
}
return results;
}
}
The database objects are defined as:
PARCEL_OBJ
create or replace TYPE parcel_obj AS OBJECT
(PARCEL_ID VARCHAR2(11),
PUBLIC_ID VARCHAR2(20));
PARCEL_TAB
create or replace TYPE parcel_tab IS TABLE OF parcel_obj;
The application fails on the line
Array array = oracleConnection.createARRAY("SCHEME_NAME.PARCEL_TAB", cpoList);
The exception message is:
java.sql.SQLException: Fail to convert to internal representation: weblogic.jdbc.wrapper.Struct_oracle_sql_STRUCT#187>
My JNDI connection is defined in my application.properties like:
spring.datasource.jndi-name=jdbc/pio
Any help would be appreciated!
As the documentation mentions.
By default, data type objects for Array, Blob, Clob, NClob, Ref,
SQLXML, and Struct, plus ParameterMetaData and ResultSetMetaData
objects are wrapped with a WebLogic wrapper.
In some cases setting the wrapping parameter to false can improve significantly the performance and allows the application to use a native driver.
I don't see a problem disabling that option since it is causing the problem when calling objects like struct in the first place.

ClassCastException with java List Iterator with Generics

I'm trying to display the names of the hotels using Hibernate. But when I'm iterating the list of hotels which I have got from the database, iter.next() gives a ClassCastException saying Object cannot be cast to Hotel class. This is my method.
public List<Hotel> getAllHotels()
{
List<Hotel> contracts = new ArrayList<Hotel>( );
Transaction tx = null;
Session session = SessionFactoryUtil.getCurrentSession();
try
{
tx = session.beginTransaction();
contracts = session.createSQLQuery("select * from HOTEL").list();
System.out.println("*** Content of the Hotel Table ***");
System.out.println("*** Start ***");
for ( Iterator<Hotel> iter = contracts.iterator(); iter.hasNext();) {
Hotel h = iter.next();
System.out.println(h.getHotelName());
}
System.out.println("*** End ***");
tx.commit();
}
catch( RuntimeException e )
{
if( tx != null && tx.isActive() )
{
try
{// Second try catch as the rollback could fail as well
tx.rollback();
}
catch( HibernateException e1 )
{
System.out.println( "Error rolling back transaction" );
}
// throw again the first exception
throw e;
}
}
return contracts;
}
I have used Generics for the List and Iterator but cannot figure out the error. Any help is appreciated.
Looks like you may need to add the entity when creating the SQLQuery.
Refer https://www.mkyong.com/hibernate/hibernate-native-sql-queries-examples/
session.createSQLQuery("select * from HOTEL").addEntity(Hotel.class).list();
Or if using your current code, iterate through the object array
List result = query.list();
for(Object object : data)
{
//Logic
}

Joining Objects in MySQL - JAVA

I used JOIN to join tables together and retrieve information. After retrieving objects I am adding that information to a table.
my query:
"SELECT L.LibPassport AS LibPassport,L.Object as LObject,G.Passport AS GPassport,"
+ "G.Object AS GObject,O.* FROM Orders AS O, Guest AS G, Librarian AS L WHERE O.Passport = G.Passport";
Firstly it gives me an error as Columns LObject not found then I changed all to only as Object , query worked smoothy but then its not adding all objects to List.
Method for sql is below:
public List<Object> getReport() {
List<Object> obj = new ArrayList<Object>();
Object x = null;
String query = "SELECT L.LibPassport AS LibPassport,L.Object as Object,G.Passport AS GPassport,"
+ "G.Object AS Object,O.*,O.Object AS Object FROM Orders AS O, Guest AS G, Librarian AS L WHERE O.Passport = G.Passport";
try {
state = conn.prepareStatement(query);
rs = state.executeQuery();
//Librarian
while(rs.next()) {
ByteArrayInputStream bais = new ByteArrayInputStream(rs.getBytes("Object"));
ObjectInputStream ois = new ObjectInputStream(bais);
x = ois.readObject();
obj.add(x);
ois.close();
bais.close();
}
}catch(SQLException | IOException | ClassNotFoundException ex) {
ex.printStackTrace();
}
return obj;
}
and then I am accessing and differentiating using instanceof e.g.
if(obj.get(i) instanceof Transaction) {
a = (Transaction) obj.get(i);
fill.add(4,a.getBorrowDate());
fill.add(5,a.getReturnDate());
}
But its not getting all the objects, it either doesn't access or only 1 object. however the same query in mysql shows me all objects.
If you want further details please let me know.

How to write sql innerquery in hibernate?

presently my method uses basic jdbc concept like this,
public static ArrayList<VehicleDetailsBean>
getAllVehicleDetails(String groupId,String clientId)
throws ClassNotFoundException, SQLException {
ArrayList<VehicleDetailsBean> vehicleDetailsList =
new ArrayList<VehicleDetailsBean>();
try {
Statement statement = connection.createStatement();
String sql ="SELECT a.vehicleno,a.lat,a.lng,a.status, "+
"a.rdate,a.rtime from latlng a,vehicle_details b where"+
"a.vehicleno=b.vehicleno and b.clientid='"+
clientId+"' and b.groupid in(select groupid from group_details"+
" where groupname='"+groupId+"' and clientid='"+clientId+"')";
ResultSet rs = statement.executeQuery(sql);
while(rs.next()) {
VehicleDetailsBean vehicleDetailsBean=new VehicleDetailsBean();
vehicleDetailsBean.setVehicleno(rs.getString("vehicleno"));
vehicleDetailsBean.setLat(rs.getString("lat"));
vehicleDetailsBean.setLng(rs.getString("lng"));
vehicleDetailsBean.setStatus(rs.getString("status"));
vehicleDetailsBean.setRdate(rs.getInt("rdate"));
vehicleDetailsBean.setRtime(rs.getString("rtime"));
vehicleDetailsList.add(vehicleDetailsBean);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
it returns an ArrayList. Now I want to change it to hibernate SO I will change above code as,
query = session.createQuery(hqlquery);//I am not getting how to write hqlquery
List<Object[]> groupList = query.list();
for(Object[] arr : groupList){
System.out.println(Arrays.toString(arr));
}
by doing this it returns List object but my method has to return ArrayList. So can any one help me to write query and return the result as ArrayList.
You can do it the ugly way:
query = session.createQuery(hqlquery); // Take a walk in Hibernate Docs for HQL Queries
List<?> groupList = query.list();
ArrayList<VehicleDetailsBean> result = new ArrayList<VehicleDetailsBean>(groupList.size());
for (Object o : groupList) {
result.add((VehicleDetailsBean) o);
}
return result;
If you want to return it as ArrayList, you can just addAll it with your ArrayList.
List<VehicleDetailsBean> groupList = (List<VehicleDetailsBean>) query.list();
vehicleDetailsList.addAll(groupList);
return vehicleDetailsList;
You can see similar question here and a way to cast here
EDIT
Or try to add entity
List<LatitudeBean> bean = (List<LatitudeBean>) session.createSQLQuery(query)
.addEntity(LatitudeBean.class).list();
//add to ArrayList here

Categories