Need help: InvocationTargetException wrapped around "java.lang.ClassCastException: java.lang.String cannot be cast to [C" using CrudRepository - spring

I'm trying to execute a very simple query with Spring Data's CrudRepsitory and Hibernate.
Repo:
public interface LabelsAllRepository extends CrudRepository<LabelsAll, Integer>{
#Query("select distinct(a.kundentext1) from LabelsAll a where a.zeichnungsnummer= :zchnr and a.revision = :rev")
String findKtxt1ByZchnrAndRev(#Param("zchnr") String zchnr, #Param("rev") String rev);
}
I've tried many different ways to call that function but nothing helps. I always get InvocationTargetException wrapped around java.lang.ClassCastException: java.lang.String cannot be cast to [C. Also theres no proper stack trace i think because i'm using reflection? I'm really not exactly sure.
#Override
public boolean isCounterForSet(String edvNb, String revision) {
boolean ret = false;
// This line is causing the exception to be thrown
String labelsAll = labelsAllRepository.findKtxt1ByZchnrAndRev(edvNb, revision);
if (!labelsAll.equals("")) {
int snCount = snCounterRepository.countSnByKtxt1(labelsAll);
ret = (snCount != 0);
}
return ret;
}
The query seems to be correct. [http-nio-8080-exec-1] DEBUG org.hibernate.SQL - select distinct labelsall0_.kundentext1 as col_0_0_ from ascom_etiketten_all labelsall0_ where labelsall0_.zeichnungsnummer=? and labelsall0_.revision=?
Could really use some help solving this problem.

The problem was caused by entity class attribute defined as char[] instead of String. Hibernate therefore tried to cast #Param("rev") String rev to char[] which it couldn't do.

Related

Spring Data Rest ava.lang.IllegalArgumentException

I am getting
java.lang.IllegalArgumentException: Cannot get property 'objects' on null object
error when I intentionally test spring data rest api simulating a user passing bad url as in
http://myurl/findByDate?year=&month="
The year and month are Integers , but in this case I am simulating the user not passing any value.
The app is using the:
public interface myRepo extends PagingAndSortingRepository<myClass, Long> {}
interface and there is no explicit controller provided in a controller class. The data rest interface provides the following:
#Query("Select c from myPOJO c where (YEAR(c.myDate) = :year AND MONTH(c.myDate) = :month)")
Page findByDate(#Param("year") int year,
#Param("month") int month,
Pageable pageable);
I can see why the exception is being thrown ... but providing a generic exception handler to handle it does not seem to resolve the issue.
#ControllerAdvice
public class ExceptionControllerAdvice {
#ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) {
ErrorResponse error = new ErrorResponse();
error.setErrorCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
error.setMessage("Please contact your administrator");
//return new ResponseEntity<ErrorResponse>(error, HttpStatus.OK);
return new ResponseEntity<ErrorResponse>(error, HttpStatus.METHOD_NOT_ALLOWED);
}
}
Any advise on how to trap this data rest exception would be appreciate it.
java.lang.IllegalArgumentException: Cannot get property 'objects' on null object
Thank you
This is resolved by using the object Integer instead of the primitive Int for the param. This appears to handle the conversion to default value and avoid nulls.
Thanks

spring data mongodb enum mapping converter

I would like code not throws exception when java code load enum value from mongo that not exists in enum code
Exemple :
java.lang.IllegalArgumentException: No enum constant fr.myapp.type.OrderOptionEnum.TELEPHONE
at java.lang.Enum.valueOf(Enum.java:238)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:819)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readCollectionOrArray(MappingMongoConverter.java:909)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1184)
Because TELEPHONE not existe in OrderOptionEnum
I juste want the code return null value
Any idea ?
Regards
you can add a custom converter implement Converter<String, OrderOptionEnum> there you implement your own convert logic from string to your enum.
something like this
public class OrderOptionEnumMongoConverter implements Converter<String, OrderOptionEnum> {
#Override
public OrderOptionEnum convert(String source) {
for (OrderOptionEnum OrderOptionEnum : OrderOptionEnum.values()) {
if (OrderOptionEnum.name().equals(source))
return OrderOptionEnum;
}
return null;
}
}
Notice !!! This converter will try to convert each string in mongo to your enum, thus may result in unwanted conversions, so make sure you do this only when needed.
you can add #ReadingConverter if you want this convert only when reading from mongo.

Storing enum property via BeanPropertySqlParameterSource fails with SQLException: Invalid conversion requested

Java, Spring JDBC v3.0.5
I defined a DTO which has among others a property of type of custom enum.
When sending it as parameters to a stored procedure call via a BeanPropertySqlParameterSource object, all other properties (that are "normal" types, like: Long, String and Boolean) work fine, except the enum type. It throws:
java.sql.SQLException: Invalid conversion requested
Looking into the StatementCreatorUtils.java method setValue() I see that it does not handle Types.CHAR which is the sqlType of the enum object (I know this from debugging - that is actually the declared type of the parameter in the SQL procedure).
Reading the same DTO (by another procedure) via a BeanPropertyRowMapper works fine.
Is this some bug or omission in Spring code?
The DTO looks like this:
public class MyDTO extends Serializable {
private Long num;
private Boolean bool;
private String str;
public static enum MyEnum { A , B }
private MyEnum en;
// getters and setters omitted
}
// the call:
new SimpleJdbcCall(m_dataSource).withProcedureName("procedureName").withSchemaName("schema").executeObject(BigDecimal.class, new BeanPropertySqlParameterSource(aMyDTO)).longValue();
I worked the problem around by making MyEnum implement the java.lang.CharSequence interface, so the isStringValue() method in the StatementCreatorUtils class "thinks" it is a string and calls:
ps.setString(paramIndex, inValue.toString());
It is the same line as a few lines above:
else if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR ||
(sqlType == Types.CLOB && isStringValue(inValue.getClass()))) {
ps.setString(paramIndex, inValue.toString());
}
which is skipped since it does not allow the CHAR sqlType.
The database used is Oracle and the actual exception is thrown from the Oracle driver, so it has a similar problem (can't convert from enum to String).
The procedure parameter is defined as "IN CHAR".
The exception thrown is:
Caused by: java.sql.SQLException: Invalid conversion requested
at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:13780)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:13682)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:14515)
at oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:10918)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:735)
at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:356)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:216)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:127)
at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:212)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:947)
Edit:
I found another workaround in the Spring forum:
paramSource.registerSqlType("en", Types.VARCHAR);
BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(pojo) {
#Override
public Object getValue(String paramName) throws IllegalArgumentException {
Object value = super.getValue(paramName);
if (value instanceof Enum) {
return value.toString();
}
return value;
}
};

How to trim white spaces from char fields pojo using hibernate and Legacy database

My table has column as char(5) and can not change it to varchar(5). So when I fetch values out from the table using hibernateTemplate , that returns added spaces with actual say single alphabet value.(A custome fix is to use .trim() method with checking NPE) but do we have a provided approach to handle this kind of situation.
PS.I am using Spring support for hibernate dao support.
(In SQL, the CHAR data type is a fixed length character string. By definition, the additional characters are padded wtih spaces.)
One way of avoiding explicit call to trim() is you can provide a lifecycle method using a #PostLoad annotation n your Enitity.
eg:
#PostLoad
protected void trim(){
if(stringAttr!=null){
stringAttr=stringAttr.trim();
}
}
I have referred discussion on similar question here
Of the suggested solutions I feel adding user type best suites the requirements and makes more sense because
1. #PostLoad (Or actually lifecycle methods) does not work with using SessionFactory with hibernate.
2. Modification in assessor could be ignored during code refractor and another developer may overlook the setters which may lead to overwriting the setter.
So I am using following solution.
1.Have one package-info.java :- This has details for typedefs being used.
2.Annotated the fields with #Type(type="MyTrimTypeString")
3.Defined a user type class MyTrimTypeString, Code for which followed reply by StepherSwensen with a slight update on nullSafeGet looks like
#Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException
{
final String val = rs.getString(names[0]);
return (val == null ? val : val.trim());
}
and nullSafeSet looks like :
#Override
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException
{
final String val = (String)value;
st.setString(index, val);
}

Unexpected ClassCastException... using EJB

I am facing a very small problem which is driving me mad..
I am calling a business method 'public List getPsubcategoryList()' from a stateless sessionbean named SlBrowseProducts .. this method used entitymanager instance to retrieve a list of Objects from Database Table mapped to Entity class named Psubcategory. this I did using a namedQuery. The list returned contains elements of type Object, I have to attach a iterator named myIterator to list and cast eachof the myIterator.next()'s to the type Psubcategory to make the result element useful and run any getters on it. However this casting returned the following error..
SEVERE: java.lang.ClassCastException: entitybeans.Psubcategory cannot be cast to entitybeans.Psubcategory
I tried googling extensively to find the cause for it.. to which I came across something called 'ClassLoader Hell' which might be causing it..
Is there any solution to this problem. Is there any other way around this... I have tried not using Iterator and instead using for loop ... but even then I have to cast.. which again lands me to the same problem..
Please Help m tight on schedule.
====================JSP PAGE==================
List<Psubcategory> subcategoryList1 = slbp.getProductSubcategories();
if(subcategoryList1.size()!=0){
for(int i=0;i<subcategoryList1.size();i++){
Psubcategory temp = subcategoryList1.get(i);
System.out.print(temp.getSubcategory());
}
}
======================SLBrowseProducts.java======================
#Stateless
#LocalBean
public class SLBrowseProducts implements TestInterface {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("INNOVATIVE-INDOORSPU");
EntityManager em = emf.createEntityManager();
#Override
public List getProductSubcategories(){
List subcategoryList=em.createNamedQuery("Psubcategory.findAll").getResultList();
return subcategoryList;
}
}
#Stateless
#LocalBean
public class SLBrowseProducts implements TestInterface {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("INNOVATIVE-INDOORSPU");
EntityManager em = emf.createEntityManager();
#Override
public List<Psubcategory> getProductSubcategories(){
List<Psubcategory> subcategoryList=
em.createNamedQuery("Psubcategory.findAll").getResultList();
return subcategoryList;
}
}
============================================================================================
List<Psubcategory> subcategoryList1 = slbp.getProductSubcategories();
for(Psubcategory temp : subcategoryList1){
System.out.print(temp.getSubcategory());
}

Resources