query inside query to 1 query postgresql - java

i have a query like this
UPDATE FOLLOWUP F SET CUSTOMER=(SELECT NAME FROM CUSTOMERS C WHERE F.CUST_ID=C.ID), PHONE=(SELECT SEARCHKEY FROM CUSTOMERS C WHERE F.CUST_ID=C.ID);
this is succesfully working in my postgresql, but not running in java
and my java function
for (final TicketLineInfo l : ticket.getLines())
if(l.getConsumption()!= 0.0 && l.getMultiply()!=l.getConsumption()) {
new PreparedSentence(s
, "UPDATE FOLLOWUP F SET CUSTOMER=(SELECT NAME FROM CUSTOMERS C WHERE F.CUST_ID=?), PHONE=(SELECT SEARCHKEY FROM CUSTOMERS C WHERE F.CUST_ID=?);"
, SerializerWriteParams.INSTANCE
).exec(new DataParams() { public void writeValues() throws BasicException {
setString(1, ticket.getCustomerId());
setString(2, ticket.getCustomerId());
}});
}
when i run this
i get error like this:
com.openbravo.basic.BasicException:
org.postgresql.util.PSQLException: ERROR: more than one row returned by a subquery used as an expression
org.postgresql.util.PSQLException:
ERROR: more than one row returned by a subquery used as an expression
my question is how do i convert the above query into one single query without a subquery.. so that i can avoid this exception and proceed with my execution OR is there any other serializer which supports this

Looks like you don't need subqueries in your query:
update FOLLOWUP as F set
Name = c.Name,
Phone = c.SearchKey
from CUSTOMERS as c
where
F.Cust_ID = C.ID and
F.Cust_ID = ?

Related

Hibernate Restrictions subquery with id of main query

I got 2 Tables with data
Main
---
id // 1
Second
---
id //1; 2
property //"a"; "b"
creationDate(DD/MM/YYYY) //01/01/2000; 02/02/2002
mainId // 1; 1
The connection is 1-*
So, what I want to do is to query my "Main" table by the property in "Second", but I want to search only the newest property.
So searching "a" must not give any result, as "b" is a newer data.
I wrota it via SQL and it looks like this:
select distinct m.id from Main m join Second s on m.id = s.mainId where s.property = 'b' and s.creationDate = (SELECT MAX(s2.creationDate) from Second s2 where s2.mainId = m.id);
I figured out some java code, but I have no idea how to use this s2.mainId = m.id part via Restrictions:
DetachedCriteria d = DetachedCriteria.forClass(Second.class, "s1");
ProjectionList proj = Projections.projectionList();
proj.add(Projections.max("s1.creationDate"));
d.setProjection(proj).add(Restrictions.eq("WHAT COMES HERE");
Or maybe should I use defferent approach?
Unformtunately I need to use Hibernate Criterion Interface as whole seach mechanismus is written via Criterion.
DetachedCriteria innerCrit = DetachedCriteria.forClass(Second.class);
innerCrit.setProjection(Projections.max("creationDate");
innerCrit.add(Restrictions.eqProperty("id", "main.id"));
DetachedCriteriaouterCrit outerCrit = DetachedCriteria.forClass(Main.class, "main");
outerCrit.createAlias("second", "second");
outerCrit.add(Subqueries.eq(second.creationDate, innerCrit));
outerCrit.add(Restrictions.eq("second.property", "b"));
This outerCrit will get you the Main object.

Parameter index out of range (1 > number of parameters, which is 0) in MySQL

Im using Spring mvc, Hibernate and Mysql, in my DAOImplement i call sql file outsite.
This is my DAO:
public List<RenterDto> searchByNamePersonalId(String name, String personalId) {
Session session = sessionFactory.openSession();
String sqlString = GetSqlUtils.getSqlQueryString(RenterDaoImpl.class, SQL_DIR + SEARCH_BY_NAME_PERSON);
List<RenterDto> list = new ArrayList<RenterDto>(0);
try {
Query query = session.createSQLQuery(sqlString);
query.setParameter(0, name);
query.setParameter(1, personalId);
list = query.setResultTransformer(new AliasToBeanResultTransformer(RenterDto.class)).list();
} catch (HibernateException e) {
logger.error("error at RenterDaoImpl.searchByNameAddress: " + e.getMessage());
} finally {
session.close();
}
return list;
}
My SQL called (SEARCH_BY_NAME_PERSON), use to search name and personalId:
SELECT
R.ID,
R.NAME,
R.ACCOUNT_ID,
R.OTP_CODE,
R.OS_TYPE,
R.MANCHINID,
R.TYPE,
R.PERSONAL_ID,
R.PHONENUMBER,
R.EMAIL,
R.ADDRESS,
R.DISTRICT_ID,
D.NAME AS DISTRICT_NAME,
R.CITY_ID,
C.NAME AS CITY_NAME
FROM
RENTER R
INNER JOIN
DISTRICT D
ON
R.DISTRICT_ID = D.ID
INNER JOIN
CITY C
ON
R.CITY_ID = C.ID
WHERE
LOWER(R.NAME)
LIKE
('%'||'?')
OR
R.PERSONAL_ID
LIKE
'%'||'%'
When I search with keyword: 'name' or 'personalId', I received an error result following as:
SqlExceptionHelper - SQL Error: 0, SQLState: S1009
SqlExceptionHelper - Parameter index out of range (1 > number of parameters, which is 0).
RenterDaoImpl - error at RenterDaoImpl.searchByNameAddress: could not execute query
How to fix this the problem ? Thank you so much !
You have this expression:
LIKE ('%'||'?')
I am guessing that you want '?' to be a parameter. But it is a lowly string, with just a single question mark.
Instead:
LIKE CONCAT('%', ?)
In general, in MySQL, you want to use CONCAT() for string concatenation.

Inner join query on Hibernate - SQL queries do not currently support iteration

I'm new to hibernate and I've this SQL query which works perfectly
SELECT count(*) as posti_disponibili from occupazione t inner join
(select id_posto_park, max(date_time) as MaxDate from occupazione
group by id_posto_park) tm on t.id_posto_park = tm.id_posto_park and
t.date_time = tm.Maxdate and t.isOccupied = 0
which gives me all the last items with isOccupied = 0
I was porting it into Hibernate, I've tried to use
result = ( (Integer) session.createSQLQuery(query).iterate().next() ).intValue()
to return posti_disponibili but i got this exception
java.lang.UnsupportedOperationException: SQL queries do not currently support iteration
How can i solve this? I cannot find the equivalent HQL query
Thank you
I would suggest you to use
Query#uniqueResult()
which will give you single result.
select count(*) .....
will always return you a single result.
Hibernate support it's own iterator-like scroll:
String sqlQuery = "select a, b, c from someTable";
ScrollableResults scroll = getSession().createSQLQuery(sqlQuery).scroll(ScrollMode.FORWARD_ONLY);
while (scroll.next()) {
Object[] row = scroll.get();
//process row columns
}
scroll.close();

JPA query with CHAR type. Was: JPA query with WHERE and EmbeddedId

Edit: Cleaning up by removing details not relevant to the problem.
The problem. JPA query returns no results.
String qstr = "select o from MyStats o where o.queue_name = :queue";
String queue = "3";
em.createQuery(qstr).setParameter("queue", queue);
I thought the problem was either in an incorrect syntax of the JPA query or in incorrect annotation of EmbeddedID. Hence I posted definitions of classes involved but told nothing about database table apart from that it was Oracle.
My test code: Read from DB, take first value and re-use that value in subsequent select query meaning that record exists. Should be there, it was just read, right?
Test
String queue = "";
String qstr1 = "select o from MyStats o";
String qstr2 = "select o from MyStats o where o.queue_name = :queue";
logger.debug("SQL query: " + qstr1);
List<MyStats> list = em.createQuery(qstr1).getResultList();
logger.debug("111 Returning results: " + list.size());
for (MyStats s : list) {
queue = s.getQueue_name();
logger.debug("Picking queue name: " + queue);
break;
}
logger.debug("SQL query: " + qstr2);
list = em.createQuery(qstr2).setParameter("queue", queue).getResultList();
logger.debug("222 Returning results: " + list.size());
Output:
SQL query: select o from MyStats o
111 Returning results: 166
Picking queue name: 3
SQL query: select o from MyStats o where o.rec_id.queue_name = :queue
222 Returning results: 0
Class definition
#Entity
public class MyStats {
private String queue_name;
private long stats_id;
... //getters and setters
}
A query without WHERE clause works correctly so as a query with a member of MyStats class.
em.createQuery("select o from MyStats o where o.stats_id = :sid").setParameter("sid", 179046583493L);
I am using Oracle 10 database, Java EE 5 SDK, Glassfish 2.1.
The problem appeared to be with the mapping of Java String type to database column CHAR type.
Database table queue_name column is defined as CHAR(20), while Java type is String.
There are few options to fix it
Replace database column CHAR type with VARCHAR
Pad query parameter value with spaces for every request
Use LIKE condition instead of equals = and add % to the end of parameter value
Speculative: Use cast
(1) Acceptable if you have control over the database table
(2) Works for the given select statement, possibly breaks for JOINs
(3) May fail to do the trick. LIKE 'a%' returns not only 'a ' but 'aa ', 'abc ', and so on
(4) This is not completely clear to me. I am not sure if it is possible to adopt:
em.createNativeQuery("select cast(queue_name as CHAR(20)) from ...");

Retrieving a value from Stored Procedure using Native SQL Hibernate

Below is the stored procedure:
create or replace procedure
proc_emp_name(v_emp out emp.emp_name%TYPE, v_empid in emp.emp_id%TYPE)
is
begin
select emp_name into v_emp from emp where emp_id = v_empid;
dbms_output.put_line('Emp Name: ' || v_emp);
dbms_output.put_line('Procedure created successfully!!!');
end;
I want to invoke this using Native SQL, followed this link but not sure how to retrieve the OUT parameter from the Procedure.
http://www.mkyong.com/hibernate/how-to-call-store-procedure-in-hibernate/
Kindly let me know the simplest way to invoke the procedure and get the results out of it.
EDIT
As suggested, checking the docs, I modified the Proc having first parameter as a SYS_REFCURSOR as follows:
create or replace procedure
proc_empname_refcursor(v_empname OUT SYS_REFCURSOR, v_deptid in emp.emp_id%type)
is
begin
open v_empname for select * from dept where dept_id = v_deptid;
end;
I am able to invoke it using NamedQuery but I don't want to add anything in the mapping files because of some other restrictions. I tried the below code for invoking the proc without using NamedQuery but it did not worked out:
Query query = session.createSQLQuery(
"CALL proc_empname_refcursor(?, :deptId)")
.addEntity(Dept.class)
.setParameter("deptId", new Integer(2));
List<Dept> departments = query.list();
for(int i=0; i<departments.size(); i++){
Dept department = (Dept)departments.get(i);
System.out.println("Dept Id: " + department.getDeptId());
System.out.println("Dept Name: " + department.getDeptName());
}
I am getting the exception:
org.hibernate.QueryException: Expected positional parameter count: 1, actual parameters: [] [CALL proc_empname_refcursor(?, :deptId)]
at org.hibernate.impl.AbstractQueryImpl.verifyParameters(AbstractQueryImpl.java:319)
at org.hibernate.impl.SQLQueryImpl.verifyParameters(SQLQueryImpl.java:201)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:145)
at com.jdbc.HibernateStartup.main(HibernateStartup.java:70)
Kindly let me know how to resolve this.
I've managed to get an out parameter from a stored procedure using the following code in Hibernate and MS SQL Server:
#Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
Connection connection = session.connection();
CallableStatement callable = null;
try {
callable = connection.prepareCall("execute [procedure] ?");
callable.registerOutParameter(1, Types.INTEGER);
callable.execute();
int id = callable.getInt(1);
return id;
} catch (SQLException e) {
(...)
} finally {
(...)
}
}
From Hibernate Docs:
You cannot use stored procedures with Hibernate unless you follow some procedure/function rules.
For Oracle, A function must return a result set. The first parameter of a procedure must be an OUT that returns a result set.

Categories

Resources