How to convert query object into a List of Strings? - java

I got a Login class:
if((!(name.equals(null) || name.equals("")) && !(password.equals(null) || password.equals(""))))
{
try{
loggedUser = checkLogin(name, hexPass.toString());
if(!loggedUser.isEmpty())
{
userdbId = loggedUser.get(0);
userdbName = loggedUser.get(1);
userdbPsw = loggedUser.get(2);
userdbType = loggedUser.get(3);
...
And a user DAO:
public List<String> checkLogin(String uname, String password) {
Session session = null;
List<String> lst = new ArrayList<String>();
try {
session = getSession();
String sql = "select * from user where uname='" + uname + "' and password='" + password + "'";
Query query = session.createSQLQuery(sql)
.addScalar("Id", StringType.INSTANCE)
.addScalar("uname", StringType.INSTANCE)
.addScalar("password", StringType.INSTANCE)
.addScalar("utype", StringType.INSTANCE);
lst = query.list();
}
catch (Exception e){
e.printStackTrace();
}
return lst;
}
The userdbId = loggedUser.get(0); generates error: 500
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.lang.String
com.se.pl.actions.LoginAction.execute(LoginAction.java:95)
I do not understand why this is happening since list of 4 strings is going to be put into 4 variables.

The error means that you have an Object and you are doing an implicit cast to String, so that's the error.
userdbId = loggedUser.get(0);
You can fix that by adding toString() method like:
userdbId = loggedUser.get(0).toString();
Of course, you are going to get the string representation for that object.
Note that if you have your own object you are going to get the following representation:
getClass().getName() + '#' + Integer.toHexString(hashCode())
In case you have this, you will need to override the toString() method in your class

You should use TypedQuery<T> instead of query and create objects of user entity type(if you have it defined - you definitely should have one) - it should look something like this (do not take this code literaly! I mainly use OpenJPA)
TypedQuery<UserEntity> query= session.createQuery("SELECT u FROM UserEntity u WHERE name=:name AND password=:password");
query.addParam("name",name);
query.addParam("password",password);

This probably should help:
Query query = session.createSQLQuery(sql)
.addScalar("Id", StringType.INSTANCE)
.addScalar("uname", StringType.INSTANCE)
.addScalar("password", StringType.INSTANCE)
.addScalar("utype", StringType.INSTANCE)
.setResultTransformer(org.hibernate.Criteria.ALIAS_TO_ENTITY_MAP);
Map row = (Map) query.uniqueResult();
lst.add((String) row.get("Id"));
lst.add((String) row.get("uname"));
lst.add((String) row.get("password"));
lst.add((String) row.get("utype"));

Related

NamedParameterJdbcTemplate substituing values with single quotes

#Autowired
NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public List<Contact> findByPhoneWithNamedParameters(String phone) {
MapSqlParameterSource namedParameters = new
MapSqlParameterSource().addValue("phone", phone);
String sqlQ = getSqlQuery(namedParameters);
namedParameters.addValue("anotherCondition", sqlQ);
String sql = "select * from Contact c where c.phone=:phone
:anotherCondition";
return namedParameterJdbcTemplate.query(sql, namedParameters, new ContactRowMapper());
}
private String getSqlQuery(MapSqlParameterSource namedParameters) {
return " and c.name='Saman'";
}
The above one is generating the query like below:
select * from Contact c where c.phone='09137390432' ' and c.name=''Saman'''
getSqlQuery() return value is embeddigng within single quotes, with that query is not working as expected.
I tried to concatenate the value directyle instead of namedParams;
But in my case, I have to avoid the SQL Injection.
How to resolve this?
You should only use named parameters with the actual values you want to pass to the query, not with whole SQL sub-parts. Otherwise it will escape also the valid SQL quotes.
So you should change your code to something like this:
private String getAdditionalSqlConditions(MapSqlParameterSource namedParameters) {
namedParameters.add("name", "Saman");
return "c.name = :name";
}
public List<Contact> findByPhoneWithNamedParameters(String phone) {
MapSqlParameterSource namedParameters = new MapSqlParameterSource().addValue("phone", phone);
String conditions = getAdditionalSqlConditions(namedParameters);
String sql = "select * from Contact c where c.phone=:phone and " + conditions);
return namedParameterJdbcTemplate.query(sql, namedParameters, new ContactRowMapper());
}

Query with 3 tables in native sql with hibernate

I have 3 tables related with their FK and I trying to do a native query selecting entities joined. I did with 2 tables joined and it worked, but it does not work with 3.
This is my generic method for it
public List<Object[]> select3Tables(String sql, String parameter,
String tableAlias, String entityName, String tableAlias2, String path,
String tableAlias3, String path2){
Transaction tx = null;
List<Object[]>returnList = null;
try {
Query query = session.createNativeQuery(sql)
.addEntity(tableAlias, entityName)
.addJoin(tableAlias2, path)
.addJoin(tableAlias3, path2)
.setParameter("parameter", parameter);
returnList = query.getResultList();
tx.commit();
} catch (HibernateException e) {
if(tx!=null) tx.rollback();
System.err.println(e.getMessage());
e.printStackTrace();
}
and here is where I triying to do it.
public List<Compra> selectCompraByPropietario(final String dniPropitario) {
Compra compra = new Compra();
String sql = "SELECT * FROM Compras c "
+ "JOIN Montes m ON c.id_compra = m.compraFK_id_compra "
+ "JOIN Propietarios p ON m.propietarioFK_id_propietario = p.id_propietario"
+ "WHERE p.dni =:parameter";
List<Object[]> list = new HibernateSession().select3Tables(sql, dniPropitario, "compras",
"backend.entities.Compra", "m", "compras.montes", "m", "propietarios.montes");
for(Object[]listData : list) {
compra = (Compra) listData[0];
data.add(compra);
}
System.out.println("tamaño de data " + data.size());
return data;
}
Currently I´m getting an error "could not determine fetch owner : null"
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.HibernateException: Could not determine fetch owner : null
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1626)
at org.hibernate.query.Query.getResultList(Query.java:165)
at backend.HibernateSession.select3Tables(HibernateSession.java:149)
at backend.repositories.CompraOperations.selectCompraByPropietario(CompraOperations.java:90)
at backend.MainBackend.main(MainBackend.java:54)
Caused by: org.hibernate.HibernateException: Could not determine fetch owner : null
at org.hibernate.loader.custom.CustomLoader.determineAppropriateOwnerPersister(CustomLoader.java:292)
any idea what am I doing wrong and how to make it work?
Thank you.
I have faced quite similar problems like you
Everything seems fine to me.
Just add a space after
+ "JOIN Propietarios p ON m.propietarioFK_id_propietario = p.id_propietario"
Write it as
+ "JOIN Propietarios p ON m.propietarioFK_id_propietario = p.id_propietario "
Hope this helps

hibernate parameter with that name [<name>] did not exist

I am running the following code.
UserService.java
String alias = "u";
String select = "SELECT u.email";
String where = "u.userId = :id";
Map<String, Object> params = new HashMap<>();
params.put("id", userId);
List<User> users = db.findRecords(User.class, alias, select, where, params);
DB.java
public <T> List<T> findRecords(Class<T> entityClass, String entityAlias, String select, String where, Map<String, Object> params) {
String sql = select + " FROM " + entityClass.getName() + " " + entityAlias;
if (where != null) {
sql = sql + " WHERE " + where;
}
Query query = entityManager.createQuery(sql);
System.out.println(sql);
if (!params.isEmpty()) {
Iterator<Entry<String, Object>> iterator = params.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Object> entry = iterator.next();
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
query.setParameter((String) entry.getKey(), (Long) entry.getValue());
}
}
return query.getResultList();
}
I am getting the following error log.
SELECT u.email FROM com.catalog.user.User u WHERE u.userId = :id
key: id, value: 28636907
Caused by: java.lang.IllegalArgumentException: Parameter with that name [id] did not exist
If the parameter is getting printed in the console then what is causing the illegal arguments exception to come up?
Please help!
1) check that it is not a typo in the parameter name :id. It's case sensitive.
2) try to execute query without parameters. It might be a problem in the entity mapping.
3) try to set parameter directly in the query without HashMap.
I think the problem here is caused by the way you are getting the params from the Map, with the Map.entrySet() method the iterated values are only available within the iteration and will be undefined outside of it, that's why the param is correctly printed during the loop and doesn't exist in the query.
If you take a look at the Map.entry documentation it says:
These Map.Entry objects are valid only for the duration of the
iteration;
I suggest that you change the way you store and use the parameters , you can simply use a List<Object> to store the parameters or just pass the id param directly in the method call:
public <T> List<T> findRecords(Class<T> entityClass, String entityAlias, String select, String where, Long id){
Then directly append this value in the query:
query.setParameter("id", id);

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to className

Code:
public void getDetails() {
try {
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
String hql = "select c.mobile, c.password FROM CrbtSubMasterDemo c where rownum<20";
Query query = session.createQuery(hql);
List<CrbtSubMasterDemo> itr = query.list();
session.getTransaction().commit();
for (CrbtSubMasterDemo pojo : itr) {//excepion line
System.out.println("[" + pojo.getMobile() + "]");
}
} catch (Exception e) {
e.printStackTrace();
}
}
CrbtSubMasterDemo is pojo mapped with the db.
When I try to run it, it gives following Exception:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.telemune.demoPojo.CrbtSubMasterDemo
at com.telemune.demoHibernate.QueryTester.getDetails(QueryTester.java:57)
at com.telemune.demoHibernate.QueryTester.main(QueryTester.java:23)
The question is query.list() is returning the list of objects of pojo class. Then why is this Exception. I am new to Hibernate, sorry if its a silly question.
When you write this:
String hql = "select c.mobile, c.password FROM CrbtSubMasterDemo c where rownum<20";
Your result set is not a List of CrbtSubMasterDemo
Try to write:
String hql = "select FROM CrbtSubMasterDemo c where rownum<20";
Another way is define a new constructor of CrbtSubMasterDemo where you pass only two fields c.mobile, c.password
so your query becomes:
String hql = "select new " + CrbtSubMasterDemo.class.getName() + "(c.mobile, c.password) FROM CrbtSubMasterDemo c where rownum<20";
If you follow this solution, remeber to add a default constructor too (without parameters), so in your pojo you have:
public CrbtSubMasterDemo(String mobile, String password) {
this.mobile = mobile;
this.password = password
}
and
public CrbtSubMasterDemo() {
}
String hql = "select c.mobile, c.password FROM CrbtSubMasterDemo c where rownum<20";
Query query = session.createQuery(hql);
Result of this will be List<Object[]>
List<Object[]> itr = query.list();
for (Object[] row : itr) {
System.out.println(String.format("mobile:%s, password:%s", row[0], row[1]));
}
if mobile and password are strings, of course. You can use a transformer to transform results directly to CrbtSubMasterDemo.
Hibernate 3.2: Transformers for HQL and SQL
FluentHibernateResultTransformer
Sir, Many times user faces this kinda requirements . Hibernate has ResultTransformer to convert a hql/sql in Object.
public CrbtSubMasterDemo{
private Stirng mobile;
private String password;
public CrbtSubMasterDemo(){
--------------
}
#####after setting the transation set whichever columns you are selecting should be given as name of property of your object
String hql = "select c.mobile as mobile, c.password as password FROM CrbtSubMasterDemo c where rownum<20";
Query query = session.createQuery(hql);
List<CrbtSubMasterDemo> itr = query.setResultTransformer(Transformers.aliasToBean(CrbtSubMasterDemo.class) ).list();
##No need to commit the transaction.
}
It will convert you query into the CrbtSubMasterDemo
Do not directly cast the result of "query.list();" to List of CrbtSubMasterDemo. As query.list() return object list. Iterate over the object list received and cast one by one to put in list List of CrbtSubMasterDemo

Need a help to create hibernate query

need a help to create hibernate query that table is jdwCustomerTlrdRef and it should take all the operation_spec = customer name. the method should return sysId.
Here is the code to review. Please help me i am new to this hibernate query.
public getCustomerTlrdRef(BigDecimal sysId) {
System.out.println("---- getAllCustomerTlrdRef " );
String query = "from JdwCustomerTlrdRef as jdwCustomerTlrdRef where jdwCustomerTlrdRef.operation_spec= '+customer_name+'";
Query q = getSessionFactory().getCurrentSession().createQuery(query);
List<JdwCustomerTlrdRef> customerTlrdRefSysId = q.list();
System.out.println(" List size: " + customerTlrdRefSysId.size());
return customerTlrdRefSysId;
}
This should work.
String query = "from JdwCustomerTlrdRef jdwCustomerTlrdRef where jdwCustomerTlrdRef.operation_spec= '+ customer_name +'";
Otherwise if you want to pass the parameter later in your code then do it this way.
String query = "FROM JdwCustomerTlrdRef jdwCustomerTlrdRef WHERE jdwCustomerTlrdRef.operation_spec = :customer_name"
then in your code you can pass the parameter this way.
query.setParameter("customer_name", theCustomerNameParameter);

Categories