Hibernate throws converting data type exception - java

I'm converting all our sql queries to use Hibernate parameters. Now when I add a parameter in my query and map it with an variable it always give me the error:
ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Error converting data type
nvarchar to bigint.
It doesn't make any sense because I added a string parameter.
The query looks like:
Query query = session.createSQLQuery("SELECT Sum([qtyrequired]) as pcs, o.materialrequireddate, itemid "
+ "FROM [materialManagement].[pcsorderrequirement] r JOIN materialmanagement.pcsorders o "
+ "ON o.id = r.pcsorderid WHERE itemid IN ( :items ) "
+ "AND Cast(o.materialrequireddate AS DATE) >= Cast(Getdate() AS DATE) "
+ "AND o.materialrequireddate <= Cast( :endDate AS DATE) "
+ "GROUP BY o.materialrequireddate, itemid")
.setString("items", items).setString("endDate", endDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
When I return to my original working query it looks like:
Query query = session.createSQLQuery("SELECT Sum([qtyrequired]) as pcs, o.materialrequireddate, itemid "
+ "FROM [materialManagement].[pcsorderrequirement] r " + "JOIN materialmanagement.pcsorders o "
+ "ON o.id = r.pcsorderid " + "WHERE itemid IN (" + items + ") "
+ "AND Cast(o.materialrequireddate AS DATE) >= Cast(Getdate() AS DATE) "
+ "AND o.materialrequireddate <= Cast('" + endDate + "' AS DATE) "
+ "GROUP BY o.materialrequireddate, itemid");
What can create this exception when I use named parameters? I'm using Hibernate 5.1 and for the database MS SQL server.

I changed my query to not cast to a date and sets the parameters with a correct type:
Query query = session.createSQLQuery("SELECT Sum([qtyrequired]) as pcs, o.materialrequireddate, itemid "
+ "FROM [materialManagement].[pcsorderrequirement] r JOIN materialmanagement.pcsorders o "
+ "ON o.id = r.pcsorderid WHERE itemid IN ( :items ) "
+ "AND Cast(o.materialrequireddate AS DATE) >= Cast(Getdate() AS DATE) "
+ "AND o.materialrequireddate <= :endDate "
+ "GROUP BY o.materialrequireddate, itemid").setParameterList("items", items.stream().map(Item::getId).collect(Collectors.toList()))
.setDate("endDate", Date.from(endDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));

Related

How to set locale with lower() or upper() with Spring Data JPA #Query?

The title basically sums it up but my query is like this,
#Query("SELECT distinct vr FROM VehicleRequest AS vr, UserUnit AS uu " +
"WHERE vr.latestAction.vehicleRequestStatus = ?1 " +
"AND LOWER(vr.appUser.fullName) LIKE %?2%" +
"AND uu.unit.deleted = false " +
"AND uu.appUser.id = vr.appUser.id " +
"AND uu.startAt <= current_timestamp " +
"AND uu.endAt >= current_timestamp " +
"AND uu.unit in ?3 " +
"ORDER BY vr.id")
Page<VehicleRequest> getFilteredRequests(VehicleRequestStatus status, String nameFilter, List<Unit> units, Pageable pageable);
I would like to take in to account of the locale with the lower() or upper() functions.

SQL Query - FindCostumerWithHighestBill

I am try to find the costumer with the highest bill using this sql that I wrote , but apparently I run into this error :
Every derived table must have its own alias
This is what I wrote:
public static void findCustomerWithHighestBill(Connection c) throws SQLException {
String query = "SELECT CustomerID, CustomerName, CITY, sum(sum_all) As 'data'\r\n"
+ "FROM (SELECT *, sum(Price) As 'sum_all'\r\n"
+ " FROM (SELECT *, Customer.NAME AS \"CustomerName\"\r\n"
+ " FROM Transactions\r\n"
+ " INNER JOIN Product ON Product.ID = Transactions.ProductID\r\n"
+ " INNER JOIN Customer ON Customer.ID = Transactions.CustomerID)\r\n"
+ " GROUP BY CustomerID, ProductID\r\n"
+ " ) \r\n"
+ "GROUP BY CustomerID\r\n"
+ "ORDER BY data DESC";
Statement statement = c.createStatement();
ResultSet set = statement.executeQuery(query);
set.next();
System.out.println("CustomerID: " + set.getInt("CustomerID") +
", Name: " + set.getString("CustomerName") + ", City: " +
set.getString("CITY") + ", Bill: " + set.getFloat("data"));
}
Can please somoane help me zith this ?
Coming back ,
It seems that indeed ad most of you says in the comments I should identify my tables first but, apparently I also have miss to avoid the duplicate ID column.
Here goes my new query:
String query = "SELECT CID, CustomerName, City, sum(sum_all) As data" +
" FROM (SELECT *, sum(PPROD) As sum_all" +
" FROM (SELECT Product.ID as PID,Customer.ID as CID,Product.Price as PPROD,City, Customer.NAME AS CustomerName" +
" FROM Transactions" +
" INNER JOIN Product ON Product.ID = Transactions.ProductID" +
" INNER JOIN Customer ON Customer.ID = Transactions.CustomerID) As t2" +
" GROUP BY CID, PID" +
" ) As t1" +
" GROUP BY CID" +
" ORDER BY data DESC;";

Unknown column 'ROWNUM' in 'where clause'

I read a lot of topics about this problem but most of them were having problem with some complex (at least for me) code;
I have followed the oracle ROWNUM Pseudocolumn guide but when I write
SELECT * FROM " + tableName + "
WHERE ROWNUM < 12;
I get this error:
Unknown column 'ROWNUM' in 'where clause'
I then tried to do like the solution suggested here Select where row number = rownum
but nothing changes.
My code looks like this:
sql = "SELECT C.* "
+ "FROM ( SELECT * "
+ " FROM " + tableName + " ) C "
+ "WHERE C.ROWNUM < 12;";
resultSet = statement.executeQuery(sql);
You can refer http://www.w3schools.com/sql/sql_top.asp.
ROWNUM is used in Oracle. Assuming you are using MySQL as you have tagged your question to MySQL.
You can change ROWNUM with limit clause
SELECT * FROM " + tableName + "
LIMIT 11;
Use the below
sql = ""
+ "SELECT C.*,ROWNUM as RECNUM "
+ "FROM ( "
+ " SELECT * "
+ " FROM " + tableName + " ) C "
+ "WHERE C.RECNUM < 12;";
resultSet = statement.executeQuery(sql);
Try this it will helpful for ur problem:
select * from (select * from " + tableName + ") "WHERE C.ROWNUM < 12;
Try this : [if you use mysql]
sql = ""
+ "SELECT C.* "
+ "FROM ( "
+ " SELECT * "
+ " FROM " + tableName + " ) C "
+ "LIMIT 11;";
resultSet = statement.executeQuery(sql);
For sql server :
SELECT TOP 12 ...

Set parameter for identical subquery in PreparedStatement

I have PreparedStatement like this:
PreparedStatement st = conn
.prepareStatement("Select * from "
+ "(select Count(*) from uch_otstyp b,prov_uch p "
+ "where b.\"ID_Poezd\"=?"
+ "and (b.\"NachKm\"*1000+b.\"NachM\")>? "
+ "and (b.\"NachKm\"*1000+b.\"NachM\")<=? "
+ "and b.\"ID_Poezd\"=p.\"ID_Poezd\" "
+ "and b.\"ID_Uch\"=p.\"ID_Uch\" "
+ "and p.\"MES\"=? "
+ "and p.\"GOD\"=? "
+ "and p.\"Nput\"=? "
+ "and b.\"Kod_Otstup\"=? "
+ "and b.\"DEPTH\"<1),"
+ ""
+ "(select Count(*) from uch_otstyp b,prov_uch p "
+ "where b.\"ID_Poezd\"=?"
+ "and (b.\"NachKm\"*1000+b.\"NachM\")>? "
+ "and (b.\"NachKm\"*1000+b.\"NachM\")<=? "
+ "and b.\"ID_Poezd\"=p.\"ID_Poezd\" "
+ "and b.\"ID_Uch\"=p.\"ID_Uch\" "
+ "and p.\"MES\"=? "
+ "and p.\"GOD\"=? "
+ "and p.\"Nput\"=? "
+ "and b.\"Kod_Otstup\"=? "
+ "and b.\"DEPTH\">=1)"
+ "and b.\"DEPTH\"<2)");
Parameter values of each subquery are identic. How can I set parameters only for one subquery and automaticaly fill parameters of another(not for each subquery)?
You could use named parameters, so that when a parameter appears multiple times in a query you would only have to specify it once. JDBC doesn't support named parameters, but you can write code to find the parameter names in a SQL string and figure out the order they appear so that the arguments can be added to the PreparedStatement. Spring-Jdbc does this for you with the NamedParameterJdbcTemplate, here's an example. This is in core spring, the package that implements the parameter-munging is org.springframework.jdbc.core.namedparam.

JPA Eclipselink NamedQuery vs Query COUNT

Cannot get a Integer back from a NamedQuery???
#NamedQuery( name = Comm.COUNTLIKEVALUEINHOLDER,
query = "SELECT COUNT(c.id) " +
"FROM Comm c " +
"JOIN c.element e " +
"WHERE c.search1 LIKE :search1 " +
"AND c.search2 = :search2 " +
"AND c.type = :type " +
"AND e.holderelement = :holder"
)
Object q = em.createNamedQuery(Comm.COUNTLIKEVALUEINHOLDER)
.setParameter("search1", "bla%")
.setParameter("search2", "bla2")
.setParameter("type", t)
.setParameter("holder", h)
.getSingleResult();
I get a Entity back and not a Long or Integer from COUNT Aggregat.
But here I get a Integer back. It's exactly the same query.
Object i = em.createQuery("SELECT COUNT(c.id) " +
"FROM Comm c " +
"JOIN c.element e " +
"WHERE c.search1 LIKE :search1 " +
"AND c.search2 = :search2 " +
"AND c.type = :type " +
"AND e.holderelement = :holder")
.setParameter("search1", "bla%")
.setParameter("search2", "bla2")
.setParameter("type", t)
.setParameter("holder", h)
.getSingleResult();
Does anybody have an idea?
Short answer:
em.createQuery is used for creation of dynamic queries. Return type is determined by the return type of the QL language ("SELECT COUNT(c.id)" in the example above).
em.createNamedQuery is used for creation of static queries. Return type can be type casted, for example:
Object q = em.createNamedQuery(Comm.COUNTLIKEVALUEINHOLDER)
.setParameter("search1", "bla%")
.setParameter("search2", "bla2")
.setParameter("type", t)
.setParameter("holder", h)
.getSingleResult();
Integer count = (Integer) q;
`
see also:http://www.objectdb.com/java/jpa/query/api

Categories