SQL statement conversion to criteria (Hibernate ) - java

I have an SQL query that I would like to convert into a criteria (Hibernate 3.3.2) to use it into my persistancy layer. That's the query :
SELECT TYPE_CHANTIER.ID,
TYPE_CHANTIER.CODE,
TYPE_CHANTIER.LIBELLE
FROM TYPE_CHANTIER
INNER JOIN CATEGORIE_CHANTIER
ON TYPE_CHANTIER.ID = CATEGORIE_CHANTIER.TYPE
INNER JOIN CHANTIER
ON CATEGORIE_CHANTIER.ID = CHANTIER.CATEGORIE
WHERE CHANTIER.ID = 26869423;
I already try a lot a combinations, but there is no result that would be good for me ... This is my code :
public TypeChantier recupererTypeChantier(Integer idChantier) {
TypeChantier retour = null;
if (idChantier != null) {
Criteria criteria = getSession().createCriteria(TypeChantier.class);
// requete
criteria.createAlias("categorieChantiers", "categorieChantiers", JoinType.INNER_JOIN);
criteria.createAlias("categorieChantiers.chantiers", "chantiers", JoinType.INNER_JOIN);
// requete
criteria.add(Restrictions.eq("chantiers.id", idChantier));
// resultat
retour = (TypeChantier) criteria.uniqueResult();
}
return retour;
}
this code return a java null pointer exception

Related

Java SQL Resultset DataTypes

I’m a java novice and have been tinkering with an existing Proc. I’m attempting to perform an out.write on a value derived from a SQL resultset 'Grid_ProjectCode’, as shown here:
sStmt=null;rs=null;sql=null;
sStmt = conn.createStatement();
sql = "select Proj_Code, Placement_ACR, Category_ID, Alt_Aisle_Shelf, Placement_Start_Dt, Placement_End_Dt, Sales_Manager from DH_CURRENT_FUTURE_INVENTORY_VW where Placement_ACR in ('banFSI_ROI', 'banFSI','FSI')";
rs = sStmt.executeQuery(sql);
while ( rs.next() )
{
String Grid_ProjectCode = rs.getString("Proj_Code");
String Dup_Placement_ACR = rs.getString("Placement_ACR");
if (plCode.equalsIgnoreCase(Dup_Placement_ACR))
{
out.write("Dupe Found");
out.newLine();
out.write(Grid_ProjectCode);
out.newLine();
}
}
if(conn != null) { rs.close(); sStmt.close(); }
The Proc fails with the following error (runs as expected when the second out.write is removed/commented):
java.lang.ClassCastException: [Ljava.lang.Integer; incompatible with
[Ljava.lang.String;
The Proj_Code field referred to in the SQL query is an NVARCHAR2 defined in an Oracle Exadata schema.
The error suggests some sort of data type mismatch, but I’m not sure how this is can be fixed; would really appreciate some guidance.
Edited to include DDL for DH_CURRENT_FUTURE_INVENTORY_vw:
CREATE OR REPLACE FORCE VIEW "UNICA_F1"."DH_CURRENT_FUTURE_INVENTORY_VW" ("PROJ_CODE", "FLAG_PROJ_REQUEST", "OBJECT_ID", "UAP_GRID_ROW_ID", "PLACEMENT_IMPRESSIONS", "SUPPLIER_CATEGORY", "PLACEMENT_CLASH", "PLACEMENT_NAME", "PLACEMENT_AISLE_SHELF", "PLACEMENT_START_DT", "PLACEMENT_RATE", "PLACEMENT_SIZE", "PLACEMENT_END_DT", "PLACEMENT_DURATION", "PLACEMENT_ACR", "SALES_VALUE", "NOTES", "STATUS", "AD_SERVER", "UNIT_NR", "SORT_ORDER", "CATEGORY_ID", "AISLE_SHELF_ID", "PLACEMENT_COUNT", "RETAIL_ACR", "ALT_AISLE_SHELF", "PLACEMENT_SIZE2", "PLACEMENT_SIZE3", "PLACEMENT_SIZE4", "PLACEMENT_SIZE5", "CREATIVE_YN", "CPM", "CREATIVE_SIZE", "PRODUCT_ID", "SALES_AREA", "IMPRESSION_GOAL", "CLIENT_CATEGORY", "CLIENT_SUB_CAT", "BRAND_NM", "FORMAT_DESC", "IMPRESSION_CPM", "IMPRESSION_VALUE", "CREATIVE_COST", "SIZE_DESC", "DELIVERY_PROCESS", "PACKAGE_FLAG", "PACK_ID", "RETARGETING_FLAG", "BATCH_FLAG", "BASE_COST", "DISCOUNT", "CATEGORY", "SALES_MANAGER") AS
Select
PROJ_CODE,
FLAG_PROJ_REQUEST,
OBJECT_ID,
UAP_GRID_ROW_ID,
PLACEMENT_IMPRESSIONS,
SUPPLIER_CATEGORY,
PLACEMENT_CLASH,
PLACEMENT_NAME,
PLACEMENT_AISLE_SHELF,
PLACEMENT_START_DT,
PLACEMENT_RATE,
PLACEMENT_SIZE,
PLACEMENT_END_DT,
PLACEMENT_DURATION,
PLACEMENT_ACR,
SALES_VALUE,
NOTES,
STATUS,
AD_SERVER,
UNIT_NR,
SORT_ORDER,
CATEGORY_ID,
AISLE_SHELF_ID,
PLACEMENT_COUNT,
RETAIL_ACR,
ALT_AISLE_SHELF,
PLACEMENT_SIZE2,
PLACEMENT_SIZE3,
PLACEMENT_SIZE4,
PLACEMENT_SIZE5,
CREATIVE_YN,
CPM,
CREATIVE_SIZE,
PRODUCT_ID,
SALES_AREA,
IMPRESSION_GOAL,
CLIENT_CATEGORY,
CLIENT_SUB_CAT,
BRAND_NM,
FORMAT_DESC,
IMPRESSION_CPM,
IMPRESSION_VALUE,
CREATIVE_COST,
SIZE_DESC,
DELIVERY_PROCESS,
PACKAGE_FLAG,
PACK_ID,
RETARGETING_FLAG,
BATCH_FLAG,
BASE_COST,
DISCOUNT,
CATEGORY,
SALES_MANAGER
from
(
select b.Proj_Code, b.Flag_Proj_Request, a.*, c.Category, d.Sales_Manager
from dh_ddp_inventory a
inner join uap_projects b on a.Object_ID = b.Project_ID
inner join dh_lkp_taxo_categ_vw c on a.Category_ID = c.Category_ID
inner join dh_ddp_Request d on a.Object_ID = d.Object_ID
where b.Flag_Proj_Request = 'Y' and a.Placement_End_Dt >= Current_date
and b.Proj_Code not in (select Proj_Code from uap_projects where Flag_Proj_Request = 'N')
Union
select b.Proj_Code, b.Flag_Proj_Request, a.*, c.Category, d.Sales_Manager
from dh_ddp_inventory a
inner join uap_projects b on a.Object_ID = b.Project_ID
inner join dh_lkp_taxo_categ_vw c on a.Category_ID = c.Category_ID
inner join dh_ddp_Request d on a.Object_ID = d.Object_ID
where b.Flag_Proj_Request = 'N' and a.Placement_End_Dt >= Current_date
)
Order By Proj_Code asc, Object_ID desc, Placement_Name asc;
Somewhere you do in some form or the other:
String[] stringArray = ...;
Integer[] intArray = (Integer[]) stringArray;
As [Ljava.lang.Integer =
array ([)
of class java.lang.Integer (L)
To drill down to the error:
try {
... code ...
} catch (ClassCastException e) {
e.printStackTrace(); // To System.err.
e.printStackTrace(System.out); // To System.out.
logger.error("OMG", e); // To logger if there is one.
throw e; // Act as is the exception was not thrown
}
Look at the stack trace, it also lists the source causing the error, together with the line number.

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

use like for integer value in namedquery Eclipselink

when use namedQuery in entity class get error
#NamedQuery(name = "Classification.search", query = "SELECT c FROM Classification c WHERE c.id LIKE :value")
Method for call namedQuery
public List<Classification> search(String value) {
Query query = getEntityManager().createNamedQuery("Classification.search", Classification.getClass()).setParameter("value", "%"+value+"%");
query.setMaxResults(10);
return query.getResultList();
}
java.lang.IllegalArgumentException: You have attempted to set a value of type class java.lang.String for parameter value with expected type of class java.lang.Integer from query string SELECT c FROM Classification c WHERE c.id LIKE :value.
but when use this method is work without Error.
public List<Classification> findLimited(String _clasif, int maxResult) {
String querySt = "SELECT c FROM Classification c WHERE c.id LIKE '%" + _clasif + "%'";
Query query = em.createQuery(querySt);
query.setMaxResults(maxResult);
List<Classification> classif;
classif = query.getResultList();
if (classif != null) {
return classif;
}
return new ArrayList<>();
}
i use eclipselink 2.6 with JPA
As per the BNF for JPQL, "LIKE" is for use with String values only. Use with non-String values would only be a vendor extension, and hence vendor-dependent. Whether it is part of a named query or criteria or string-based JPQL is irrelevant.
like_expression ::= string_expression [NOT] LIKE pattern_value [ESCAPE escape_character]
i solve that by this code.
public List<Classification> search(String value) {
Query query = getEntityManager().createQuery(getNamedQueryCode(entityClass, "Classification.search").replace(":value", value));
query.setMaxResults(10);
return query.getResultList();
}
this method get namedQuery string from entity class by nameKey and class.
private String getNamedQueryCode(Class<? extends Object> clazz, String namedQueryKey) {
NamedQueries namedQueriesAnnotation = clazz.getAnnotation(NamedQueries.class);
NamedQuery[] namedQueryAnnotations = namedQueriesAnnotation.value();
String code = null;
for (NamedQuery namedQuery : namedQueryAnnotations) {
if (namedQuery.name().equals(namedQueryKey)) {
code = namedQuery.query();
break;
}
}
if (code == null) {
if (clazz.getSuperclass().getAnnotation(MappedSuperclass.class) != null) {
code = getNamedQueryCode(clazz.getSuperclass(), namedQueryKey);
}
}
//if not found
return code;
}

How do I create my query with Hibernate Criteria

I have to create the following query with Criteria:
SELECT r.*,(
SELECT COUNT(*) FROM APP.P_FORM_QUESTION_ANSWER qa
WHERE qa.J_STATUS = 'CORRECT'
AND qa.J_FORM_ID = r.J_FORM_ID AND qa.J_AUTHOR_ID = r.J_AUTHOR_ID
AND qa.J_FORM_RESULT_ID = r.J_ROW_ID
) as correctCount
FROM APP.P_FORM_RESULT r
WHERE r.J_FORM_ID = '123456'
ORDER BY correctCount DESC;
I try to use DetachedCriteria for extra column, but I do not see how to represent :
"qa.J_FORM_ID = r.J_FORM_ID AND qa.J_AUTHOR_ID = r.J_AUTHOR_ID
AND qa.J_FORM_RESULT_ID = r.J_ROW_ID"
in the DetachedCriteria, and add my DetachedCriteria as a new column
Criteria criteria =
HibernateUtil.getSession().createCriteria(FormResult.class, "formResult");
criteria.add(Restrictions.eq("formResult.formId", formId));
DetachedCriteria correctCount =
DetachedCriteria.forClass(QuestionAnswer.class, "questionAnswer");
correctCount.add(
Restrictions.eq("questionAnswer.status",QuestionAnswerStatus.CORRECT));
// How to retrieve 'formResult' ?
correctCount.add(Restrictions.eq("questionAnswer.formId", "formResult.formId"));
// How to retrieve 'formResult' ?
correctCount.add(Restrictions.eq("questionAnswer.authorId", "formResult.authorId"));
// How to retrieve 'formResult' ?
correctCount.add(
Restrictions.eq("questionAnswer.formResult.rowId", "formResult.rowId"));
correctCount.setProjection(Projections.rowCount());
// How to add my DetachedCriteria as a new column
criteria.setProjection(Projections.alias(correctCount, "correctCount"));
The Lines with comments are the lines for which I cannot find the solution.
Finally, I created a different SQL query that gives me the same result:
SELECT r.J_ROW_ID, COUNT(DISTINCT qa.J_ROW_ID) as correctCount
FROM APP.P_FORM_RESULT r left join APP.P_FORM_QUESTION_ANSWER qa on qa.J_FORM_ID = r.J_FORM_ID AND qa.J_AUTHOR_ID = r.J_AUTHOR_ID AND qa.J_FORM_RESULT_ID = r.J_ROW_ID AND qa.J_STATUS = 'CORRECT'
WHERE r.J_FORM_ID = '123456'
GROUP BY r.J_ROW_ID
ORDER BY correctCount DESC;
And I used HQL because I cannot find how to do it in Criteria:
// HQL Query to retrieve the list of FormResult IDs
StringBuilder hql = new StringBuilder();
hql.append("SELECT r.id");
hql.append(" FROM QuestionAnswer qa RIGHT JOIN qa.formResult as r");
hql.append(" WHERE r.formId = :formId AND (qa.status = :status OR qa.status IS NULL)");
hql.append(" GROUP BY r.id");
hql.append(" ORDER BY COUNT(DISTINCT qa.id) DESC"));
Query query = HibernateUtil.getSession().createQuery(hql.toString());
query.setParameter("formId", formId);
query.setParameter("status", QuestionAnswerStatus.CORRECT);
// Retrieve the list of FormResult objects from the list of IDs previously retrieved
List<Long> result = query.list();
if (result != null && !result.isEmpty()) {
for (Long resultId : result) {
formResults.add(getData(FormResult.class, resultId));
}
}
The downside is that I have to retrieve each FormResult one by one from my list of IDs retrieved by my HQL query

Hibernate Return integer value

I am new to hibernate . I want to pass 2 column values and want hibernate to return primary key of that table.
String queryString = "select perId from Permission where document.docId=1 and user.id=2";
return getHibernateTemplate().find(queryString);
But this method return List.
How can i return int value.
Use the uniqueResult() method in Query. see here for an example or read the api here.
Here is an example. Replace the place holders as need to use them.
sessionFactory = getHibernateTemplate().getSessionFactory();
Session session = sessionFactory.getCurrentSession();
Query query = session
.createQuery("select value from table where ...");
query.setParameters("param1", value1);
result = (Type) query.uniqueResult();
You could do something like:
String sql = "select count(*) from table where ...";
BigDecimal count = (BigDecimal) hibernateTemplate.execute(
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
SQLQuery query = session.createSQLQuery(sql);
return (BigDecimal) query.uniqueResult();
}});
return count;
Here is another way using addScalar:
Query query = session.createQuery("select value from table where param1 = :param1").addScalar("value", Type);
query.setParameters("param1", value1);
result = (Type) query.uniqueResult();
Example of String:
Query query = session.createQuery("select value from table where param1 = :param1").addScalar("value", StandardBasicTypes.STRING);
query.setParameters("param1", value1);
result = (String) query.uniqueResult();

Categories