Unable to cast the resultant of the query into desired object in hibernate - sql

I am not able to cast the query result to Desired Object UserTransactionInADay.
Here is my implementation
#Override
public UserTransactionInADay getTodaysActivity() {
Date date = new Date();
String modifiedDate= new SimpleDateFormat("yyyy-MM-dd").format(date);
Session session = getSession();
session.clear();
#SuppressWarnings("unchecked")
Query qry = session
.createQuery(
"Select u.infoDate, sum(u.totalActiveUsers) as totalActiveUsers, sum(u.plotsVisited) as plotsVisited, sum(u.totalDataSet) as totalDataSet, sum(u.totalAlerts) as totalAlerts, sum(u.totalCropStages) as
totalCropStages, sum(u.activitiesClosed) as activitiesClosed, sum(u.totalPlotInput) as totalPlotInput, sum(u.totalHarvest) as totalHarvest from UserTransactionInADay u where u.infoDate = ? group by u.infoDate");
qry.setString(0, modifiedDate);
List<UserTransactionInADay> userTransactionInADay = qry.list();
return userTransactionInADay.get(0);
}
Error I thrown like this
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.raghu.model.UserTransactionInADay
com.raghu.dao.CropinDaoImpl.getTodaysActivity(CropinDaoImpl.java:92)
com.raghu.service.CropinServiceImpl.getTodaysActivity(CropinServiceImpl.java:68)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

I think you need to review some of the Hibernate docs a bit. You are selecting a bunch of data and trying to cast it to an entity (I assume) collection.
What your query will return is an Object[][].
Assuming your UserTransactionInADay has the appropriate constructor, you'll want to do something like this:
"SELECT NEW UserTransactionInADay(u.infoDate, sum(u.totalActiveUsers)
AS totalActiveUsers, SUM(u.plotsVisited) AS plotsVisited,
SUM(u.totalDataSet) AS totalDataSet, SUM(u.totalAlerts) AS totalAlerts,
SUM(u.totalCropStages) AS totalCropStages, SUM(u.activitiesClosed) AS activitiesClosed,
SUM(u.totalPlotInput) AS totalPlotInput, SUM(u.totalHarvest) AS totalHarvest)
FROM UserTransactionInADay u WHERE u.infoDate = ? GROUP BY u.infoDate"
This will return UserTransactionInADay objects, again, assuming there is an appropriate constructor for that type.

Related

jooq query using bind variables

I using bind variable to do a batch update using below code
`var balanceUpdate = dslContext.batch(
dslContext.update(BALANCE)
.set(BALANCE.BALANCE, (BigDecimal) null)
.where(BALANCE.ID.eq((String) null)));
balances.forEach(balance -> {
balanceUpdate.bind(
balance.getAmount()
balance.Id);
});
int[] execute = balanceUpdate.execute();
`
Above code work well, but now i want to use bind with array of arguments like
var balanceUpdate = dslContext.batch(
dslContext.update(BALANCE)
.set(BALANCE.BALANCE, (BigDecimal) null)
.where(BALANCE.ID.eq((String) null)));
var arguments = balances.stream()
.map(balance ->
new Object[] {
balance.getAmount(),
balance.Id
}).collect(Collectors.toList());
int[] execute = balanceUpdate.bind(arguments).execute();
I get exception
java.lang.ArrayStoreException: arraycopy: element type mismatch: can not cast one of the elements of java.lang.Object[] to the type of the destination array, java.math.BigDecimal
at org.jooq_3.14.4.ORACLE12C.debug(Unknown Source)
at java.base/java.util.Arrays.copyOf(Arrays.java:3722)
at org.jooq.tools.Convert.convertArray(Convert.java:357)
at org.jooq.tools.Convert.convertArray(Convert.java:345)
at org.jooq.tools.Convert$ConvertAll.from(Convert.java:603)
at org.jooq.tools.Convert.convert0(Convert.java:392)
at org.jooq.tools.Convert.convert(Convert.java:384)
at org.jooq.tools.Convert.convert(Convert.java:458)
at org.jooq.tools.Convert.convertArray(Convert.java:363)
at org.jooq.tools.Convert.convertArray(Convert.java:345)
at org.jooq.tools.Convert$ConvertAll.from(Convert.java:614)
at org.jooq.tools.Convert.convert0(Convert.java:392)
at org.jooq.tools.Convert.convert(Convert.java:384)
at org.jooq.tools.Convert.convert(Convert.java:458)
at org.jooq.impl.AbstractDataType.convert(AbstractDataType.java:534)
at org.jooq.impl.DefaultDataType.convert(DefaultDataType.java:86)
at org.jooq.impl.DSL.val(DSL.java:24409)
at org.jooq.impl.DSL.val(DSL.java:24377)
at org.jooq.impl.Tools.field(Tools.java:1794)
at org.jooq.impl.Tools.fields(Tools.java:1865)
at org.jooq.impl.BatchSingle.executePrepared(BatchSingle.java:226)
at org.jooq.impl.BatchSingle.execute(BatchSingle.java:170)
According docs it should work ? Atleast it works without explicit casting when using jdbc. Is there anyway to get it work to sent bind variables only once instead of many times like in first example?
I think you're calling the wrong BatchBindStep.bind(Object...) method, or at least not in the way you're expecting. There's currently no overload accepting a collection of type List<Object[]>. So, what you should do instead is create an Object[][] type for your bind variable sets:
Object[][] arguments = balances
.stream()
.map(balance -> new Object[] {
balance.getAmount(),
balance.Id
}).toArray();

offsetDateTime illegalArgumentException nhibernate

i am trying to map offsetDateTime to type SQL but i am not sure how to solve the 2 types.
inside my method i am updating the date with
List<Items> listItems = repository.fetchitemById(Ids);
OffsetDateTime date = OffsetDateTime.now();
if (listItems.size() > 0 && !isNull(listItems.get(0).getDate())) {
date = listItems.get(0).getDate();
}
the query is inside the repository a crudRepository with the date on it al already verified the order in the interface and the query they all match
when i evaluate the expression
listItems.get(0).getDate()
i get
Method threw 'java.lang.IllegalArgumentException' exception.
Projection type must be an interface!
java.lang.IllegalArgumentException: Projection type must be an interface!
Also inside the schema the date is a TIMESTAMP with NULL DEFAULT NULL
any thoughts
try this
List<Items> listItems = repository.fetchitemById(Ids);
OffsetDateTime date = OffsetDateTime.now();
if (listItems.size() > 0){
if(!isNull(listItems.get(0).getDate())) {
date =Timestamp.valueOf(listItems.get(0).getDate().toLocalDateTime);
}
}

ClassCastException even after type casting

I got a problem with iterating List which got prepared from HQL.
I am querying DB on a single table mapped to very simple class.
After iterating the same list and type casting to same class during iteration I am getting ClassCastException.
Code :
import HectorRequest;
import EDIMigrateData;
SessionFactory factory = HibernateUtil.getSessionFactory();
Session session = factory.getCurrentSession();
Transaction tx = session.beginTransaction();
Query qry = session.createQuery("select hr from HectorRequest hr");
List result = qry.list();
for (Iterator it = result.iterator(); it.hasNext();) {
Object o = it.next();
if(o instanceof HectorRequest){
HectorRequest h = (HectorRequest) o;
System.out.println("ID: " + h.getId());
}
}
I wonder here If I am typecasting to the same class it is giving ClassCastException.
if(o instanceof HectorRequest) {
HectorRequest h = (HectorRequest) o;
System.out.println("ID: " + h.getId());
}
The control is not coming into the above if statement.
If I remove the above IF condition it is throwing
java.lang.ClassCastException: HectorRequest
Below is my hibernate mapping xml for HectorRequest class.
Below is my Hibernate.cfg.xml
?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property><property name="hibernate.connection.url">jdbc:oracle:thin:#//apludc01clu20-scan-oravip.dci.bt.com:61901/C2BM2_ANY</property><property name="hibernate.connection.username">s3</property><property name="hibernate.connection.password">**</property><property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property><property name="hibernate.default_schema">s3</property><property name="show_sql">true</property><property name="hibernate.current_session_context_class">thread</property><mapping resource="resources/config/hector_request.hbm.xml"></mapping></session-factory></hibernate-configuration>
Below is the output:
Hibernate: select hectorrequ0_.ID as ID0_, hectorrequ0_.ROUTER_TEL as ROUTER2_0_, hectorrequ0_.FLAGVALUE as FLAGVALUE0_, hectorrequ0_.FLAGPOS as FLAGPOS0_, hectorrequ0_.ACCOUNTNO as ACCOUNTNO0_, hectorrequ0_.CUSTOMERIDENTITY as CUSTOMER6_0_, hectorrequ0_.CRMSOURCE as CRMSOURCE0_, hectorrequ0_.DATASOURCE as DATASOURCE0_ from s3.hector_request hectorrequ0_
java.lang.ClassCastException: HectorRequest
at NotifyMain1.main(NotifyMain1.java:37)
Can someone help what is missing and wrong here.
It is because of the data returned by the query "select hr from HectorRequest hr" is not "HectorRequest". It probably is a database data type (string, number, date, time, etc). So you have to build your "HectorRequest" object using the data returned by the query and not directly assign to it with a cast.

jdbcTemplate query row map date column generically

I have a database with a date column, and when I perform a query I get each row as a Map of column names to column values. My problem is I do not know how to generically get the date column.
I am simply trying to cast it to a String at the moment, then parse it as java.util.Date, but this errors at the cast, and I am otherwise unsure as to how I can get the data?
This code is supposed to work with Sybase and Oracle databases too, so a generic answer would be greatly appreciated!
private static final String USER_QUERY = "SELECT USERNAME, PASSWORD, SUSPEND_START_DATE, SUSPEND_END_DATE FROM USERS";
public User readUsers(Subjects subjects) throws SubjectReaderException {
/* Perform the query */
List<User> users = new ArrayList<User>();
List<Map<String, Object>> rows = jdbcTemplate.queryForList(USER_QUERY);
/* Map the returned rows to our User objects */
for (Map<String, Object> row : rows) {
String username = (String) row.get("USERNAME");
/* Check if the user is suspended */
if(checkUserIsSuspended(row)){
continue;
}
User user = new User();
user.setUsername(username);
user.setPassword((String) row.get("PASSWORD"));
users.add(user);
}
return users;
}
private boolean checkUserIsSuspended(Map<String, Object> row) throws SubjectReaderException {
final String startDateString = (String) row.get("SUSPEND_START_DATE"); // this errors
if (startDateString != null) {
final String endDateString = (String) row.get("SUSPEND_END_DATE");
if (null != endDateString) {
return checkDate(startDateString, endDateString); // this just compares the current date etc
}
/* Return true if the Suspended start date is not null, and there is no end date column, or it is null */
return true;
}
/* Return false if the Suspended start date String is null - i.e. they have not been suspended */
return false;
}
The error:
java.lang.ClassCastException: com.sybase.jdbc3.tds.SybTimestamp cannot be cast to java.lang.String
It will always give this error because you are casting the Object com.sybase.jdbc3.tds.SybTimestamp to String.
Why don't you make this check directly in the SQL instead of creating a filter? Something like
SELECT USERNAME, PASSWORD, SUSPEND_START_DATE, SUSPEND_END_DATE
FROM USERS WHERE SUSPEND_START_DATE >= ?
and now you can use the queryForList passing as parameter the current time.
Another way for you to avoid this direct casts is using RowMapper. This way you can use ResultSet#getDate(String) and you won't be needing to cast anything as the JDBC driver will take care of the conversion for you :)

RuntimeBinderException on dynamic Linq with Facebook C# SDK

I am using the Facebook C# SDK in a canvas app.
When running this code...
public IEnumerable<string> GetFansIds(string pageId, IEnumerable<string> userIds)
{
if (userIds.Count() == 0)
return new List<string>();
var fb = new FacebookApp();
string query = String.Format("select uid from page_fan where uid IN ( {0} ) and page_id = {1}",
String.Join(",", userIds),
pageId
);
dynamic result = fb.Fql(query);
return result.Select((Func<dynamic, string>)(x => x.uid)).ToList();
}
I get the following Exception:
RuntimeBinderException: Cannot perform runtime binding on a null reference
The code does the following:
It performs a FQL query to get an JsonArray contaning JsonObject each with a uid Property (containing the uids of the users that are not fan of some fanpage.
The Select just converts all the dynamic objects into a List<string>
The FQL part just works correctly as i can see the results in the debugger.
The problem is with the Select that I can't make it work.
How can I fix the dynamic lambda ??? (Please don't just tell me to use a foreach, which is what I am currently doing right now)
The problem is that extension methods cannot be used on dynamic objects. Cast the result of the query to a JsonArray and then you can use linq expressions on the JsonArray.
var result = (JsonArray)fb.Fql(query);
return result.Select((Func<dynamic, string>)(x => x.uid)).ToList();