Ljava.lang.Object; cannot be cast to com.duncansolutions.databus.bean.Fdjobs - java

In my code
List<Fdjobs> fdjobs=new ArrayList<Fdjobs>();
fdjobs = (ArrayList<Fdjobs>)genericDao.namedQuery(Fdjobs.QUERYJOBS, hm);
Integer deactivateValue=new Integer(0);
for (Fdjobs job : fdjobs) {
job.setActiveJob(deactivateValue);
job.addFDJobHistory();
genericDao.update(job);
}
if the size of the result list fdjobs is zero i dont get ant error but if the size is more than zero i am getting the error
[Ljava.lang.Object; cannot be cast to com.duncansolutions.databus.bean.Fdjobs

nameQuery() method not returning the Type
ArrayList<Fdjobs>
please debug it. you can use
ArrayList<Object>
for this.

The error is simple: you get a Object[] ([Ljava.lang.Object) instead of a Fdjobs object in the List returned from your namedQuery.
So the bug is either in your for-each loop or in namedQuery which depends on what you want to achieve.

Related

Spring - jdbcTemplate failed to get Pair object

Can I get Pair as an output for jdbcTemplate? I tried the following (which work for separate Integers)
Pair<Integer, Integer> result = jdbcTemplate.queryForObject(GET_PAIR, new Object[]{}, Pair.class);
But it returns exception
org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorrect column count: expected 1, actual 2
at org.springframework.jdbc.core.SingleColumnRowMapper.mapRow(SingleColumnRowMapper.java:92)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:60)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:703)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:639)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:690)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:732)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:800)
Tried with org.apache.commons.lang3.tuple.Pair
queryForObject requires one result and just one result. So when you get EmptyResultDataAccessException it means that query for Object didn't find anything.
However I still don't think it will work, even if you get a result. A better way is to use a RowMapper.
jdbcTemplate.query(GET_PAIR, (rs, i) -> new Pair(rs.getInt(1), rs.getInt(2)))
Which will allow you to map the elements to a pair (this will return a list, one for each row).

ClassCastException when collecting to set

I'm experiencing a ClassCastException with the following piece of code.
Set<Long> purchaseIds = confirmationCodeToPurchase
.entrySet()
.stream()
.map(Map.Entry::getValue)
.map(purchase -> (Long)purchase.getPurchaseId())
.collect(Collectors.toSet()))
confirmationCodeToPurchase is a map from a confirmation code (String) to a Purchase type.
I'm extracting just the values of the map (the purchases), getting the purchaseId of each, and putting them into a set.
I get this error:
java.lang.ClassCastException: java.lang.Long cannot be cast to Purchase
and the line at which it errors is the collection line. .collect(Collectors.toSet()))
From your error description, it looks like your method purchase.getPurchaseId() returns an object that is not of type Long. That's why you get a class cast exception. Instead of casting, you can build the Long object from the return value of this method, assuming it is either String or an integer type.
Replace
.map(purchase -> (Long)purchase.getPurchaseId())
with
.map(purchase -> Long.valueOf(purchase.getPurchaseId()))

Cast int to long in Java

This questions has many answers and I have seen them. I have code that has been working but today suddenly it starting throwing java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
for the line
return null == input.get(keyName) ? 0L : (long) input.get(keyName);
Error is coming from (long) input.get(keyName). I wonder why it starting breaking all of sudden. (long) input.get(keyName) this looks good to me.
I thought of doing ((Integer) input.get(keyName)).longValue() but was getting java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer as map sometimes contains long values. Any suggestions
Stacktrace:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at accountservice.adapter.batch.testJob.SyncDriverPartitioner.getLongValueFromMap(SyncDriverPartitioner.java:78) ~[classes/:?]
at accountservice.adapter.batch.testJob.SyncDriverPartitioner.partition(SyncDriverPartitioner.java:47) ~[classes/:?]
at accountservice.adapter.batch.testJob.SyncDriverPartitioner$$FastClassBySpringCGLIB$$6f3315e4.invoke(<generated>) ~[classes/:?]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.18.RELEASE.jar:4.3.18.RELEASE]
You can take advantage of the fact that all numeric primitive wrappers extend java.lang.Number:
return null == input.get(keyName) ? 0L : ((Number) input.get(keyName)).longValue();
As to why it started giving errors suddenly; really the only likely reason is that up until it started failing, you were always putting java.lang.Long objects in the input Map, and it changed so you're also putting java.lang.Integer in them now.
It's quite easy for that to happen with auto-boxing and numeric constants:
long v = 42;
input.put("key", v); // Puts a java.lang.Long in the map
input.put("key", 42); // Puts a java.lang.Integer in the map
input.put("key", 42L); // Puts a java.lang.Long in the map
You can avoid it by declare your Map type-safely (Map<String, Long>). If you do that, input.put("key", 42) will give a compile-time error.
Rather than casting an int to a long I would suggest:
return null == input.get(keyName) ? 0L : Integer.toUnsignedLong(input.get(keyName))
At least this way you should get some more information about why it cannot be converted to a long rather than just a ClassCastException
Answer Update
Based on your comments I guess you are going to have to check type of the entry in Map before processing it, I would suggest the following:
Object keyValue = input.get(keyName);
if (null == keyValue) return 0L;
String valueType = keyValue.getClass().getTypeName();
if (valueType.equals(Long.class.getTypeName())) {
return (long) keyValue;
}
if (valueType.equals(Integer.class.getTypeName())) {
return Integer.toUnsignedLong((int) keyValue);
}
throw new TypeMismatchException(String.format("Type '%s' is not supported...", valueType));
This will let you define different operations for different types of entry, it is extendable to any types you want to support. You can tweak the exception thrown as well to provide you relevant information.
The snippet above shows you the actual type so that you can extend your code to support that type, or work out why something of that type got into your map.
It should be noted that it would probably be better to do this when data is entered into the map, not when it's taken out of the map. In which case you should be able to change your map to a type . It's always better to sanitise your imputes than trying to deal with a mishmash of mixed data types at a later date.

Obtain java primitive from mongo aggregation without a new output class

I have an aggregation:
AggregationResults<Integer> result = mongoTemplate.aggregate(
Aggregation.newAggregation(
Aggregation.group().count().as("value"),
Aggregation.project("value").andExclude("_id"),
MyData.class, Integer.class);
In the mongo shell, when I don't have to map an object, I get: { "value" : 2 }
However, I get the following error when trying to map this lone value: org.springframework.data.mapping.model.MappingException: No mapping metadata found for java.lang.Integer
Can I get around having to create a new output type class, when I only want to get a single java primitive?
Note: I'm going this approach instead of db.collection.count() for the sharding inaccuracies stated here - https://docs.mongodb.com/manual/reference/method/db.collection.count/#sharded-clusters
AggregationResults<DBObject> result = mongoTemplate.aggregate(
Aggregation.newAggregation(
Aggregation.group().count().as("value"),
Aggregation.project("value").andExclude("_id"),
MyData.class, DBObject.class);
int count = (Integer) result.getUniqueMappedResult().get("value");
So, not exactly what I wanted, because I still have to traverse over an object, but it's not any more code than I had before and I didn't need to make another class as the outputType.

Expression Value in Jasper Report: "Cannot cast from String to Boolean" error

This is my expression code:
($F{Personel_ODEME}.equals(Boolean.TRUE)) ? "PAID" : "NO PAID"
If Personel is paid, her/his Jasper tax report will read PAID, otherwise NO PAID. In the DB, this field is Boolean type, but the expression is returning a String type. So I am getting a Cannot cast from String to Boolean error.
The problem stems from your test $F{Personel_ODEME}.equals(Boolean.TRUE), which Jasper is thinking is a String to Boolean comparison, and doesnt like. To fix this, try this:
($F{Personel_ODEME}.equals(Boolean.TRUE.toString())) ? "PAID" : "NO PAID"
This will result in a String to String comparison.
It is good to note that In Java, a "true".equals(Boolean.TRUE) would result to false.
edit:
This appears to be a Jasper 'PrintWhen' expression, which allows you to determine whether to print the contents of a cell or not. It is expecting Boolean.TRUE or Boolean.FALSE as its return values. When you return "PAID", Jasper tries to evaluate that String as a Boolean, which it cant, so it throws the exception.
OK, I fixed it. I changed $F{Personel_ODEME}'s type to String, then it worked like a charm.
You have to change the Class Expression for the field to java.lang.String as it will be java.lang.Boolean by default. When it evaluates your if and tries to return "PAID" or "NO PAID", the field tries to convert that to Boolean so it can be displayed.
All credit goes to:
http://jasperforge.org/plugins/espforum/view.php?group_id=83&forumid=101&topicid=61775
Try this:
Boolean.valueOf($F{Personel_ODEME}.equals('TRUE')) ? "PAID" : "NO PAID"
($F{Personel_ODEME}==true?"PAID":"NO PAID")
Note: true(keyword) is case sensitive. And should not be capital(TRUE)

Categories