I am new to Java, I am trying to call a stored procedure from Java.
I am getting this exception for this code
#SuppressWarnings("unchecked")
List<Object> queryForList(String procName, Map<String, Object> map, CommonVO commonVO) {
List<Object> resultSetList = null;
Date connectionAttemptStartDate = null;
Date cidbQueryStartDate = null;
List<String> jndiNameList =null;
String jndiName = null;
try {
resultSetList = super.queryForList(procName, map);
}catch(Exception e) {
isError = true;
//exception = e;
System.out.println(e.getMessage());
exception=ExceptionUtils.validateCreateCIDBException(e);
}
return resultSetList;
}
My XML file here
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="SP">
<parameterMap id="objectParameters" class="java.util.Map">
<parameter property="valueAddedOfferList" jdbcType="VALUE_ADDED_OFFER_LIST" typeName="VALUE_ADDED_OFFER_LIST" typeHandler="com.bam.vision.dao.db.typehandler.ValueAddedOfferListTypeHandlerCallback" mode="OUT" />
<parameter property="errorCode" jdbcType="INTEGER" javaType="java.lang.String" mode="OUT"/>
<parameter property="errorMessage" jdbcType="CHAR" javaType="java.lang.String" mode="OUT"/>
</parameterMap>
<procedure id="retrieve_value_added_offer" parameterMap="objectParameters" timeout="2">
{call retrieve_value_added_offer(?,?,?)}
</procedure>
</sqlMap>
Getting exception like here
--- Cause: java.lang.ClassCastException: java.math.BigDecimal incompatible with java.lang.String; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in retrieve_value_added_offer.xml.
--- The error occurred while applying a parameter map.
--- Check the SP.objectParameters.
--- Check the output parameters (retrieval of output parameters failed).
--- Cause: java.lang.ClassCastException: java.math.BigDecimal incompatible with java.lang.String
This line in your XML file looks suspicious to me:
<parameter property="errorCode" jdbcType="INTEGER" javaType="java.lang.String" mode="OUT"/>
What type is the errorCode code parameter in your stored procedure?
You have jdbcType="INTEGER", which suggests it's a number, but you also have javaType="java.lang.String", which suggests it's a string. Clearly it can't be both. You haven't included the declaration of your stored procedure so it's impossible to tell which one it actually is.
If your error code is an integer, try changing javaType="java.lang.String" to javaType="java.lang.Integer" (or if that fails, javaType="java.math.BigDecimal" instead). If your error code is a string, change jdbcType="INTEGER" to jdbcType="STRING".
Related
For the field type text_general getbeans() method returning that field value as ArrayList() but field in pojo is String(While indexing same pojo was used).Also I have multiValued attribute to false.
managed-schema:
<field name="description" type="text_general" indexed="true" stored="true"/>
pojo-field :
#Field("description")
private String description;
//getter-setter method
Java-code:
SolrClient client = new HttpSolrClient.Builder("http://localhost:8983/solr/audiovideo").build();
Scanner sc = new Scanner(System.in);
System.out.println("Enter Serach : ");
String search = sc.nextLine();
SolrQuery query = new SolrQuery();
query.setQuery("description:" + search);
query.setStart(0);
QueryResponse response = client.query(query);
List<AudioVideoPojo> results = response.getBeans(AudioVideoPojo.class);
Exception:
Exception in thread "main" org.apache.solr.client.solrj.beans.BindingException: Could not instantiate object of class com.mycompany.solrdemo1.AudioVideoPojo
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBean(DocumentObjectBinder.java:71)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBeans(DocumentObjectBinder.java:50)
at org.apache.solr.client.solrj.response.QueryResponse.getBeans(QueryResponse.java:618)
at com.mycompany.solrdemo1.Main.getDataSolrFromDatabase(Main.java:155)
at com.mycompany.solrdemo1.Main.main(Main.java:131)
Caused by: org.apache.solr.client.solrj.beans.BindingException: Exception while setting value : [India International Music Festival] on private java.lang.String com.mycompany.solrdemo1.AudioVideoPojo.description
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.set(DocumentObjectBinder.java:455)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.inject(DocumentObjectBinder.java:438)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBean(DocumentObjectBinder.java:67)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field com.mycompany.solrdemo1.AudioVideoPojo.description to java.util.ArrayList
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:764)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.set(DocumentObjectBinder.java:449)
Set multiValued attribute to false. As per reference guide, it defaults to false for fieldTypes. But it is not honouring the default.
I have a persistend Book Class with the following properties
PropertyName -> HibernateMappingType -> JavaType
id -> long -> long
title -> text -> String
author -> string -> String
systemId -> long -> long
status -> boolean -> boolean
fullClassification -> string -> string
And my table description looks like this:
So far everything seems good, but when I try to fetch all the values in the table I get the following Exception Message:
20:04:43,832 TRACE BasicExtractor:61 - extracted value ([classifi1_1_0_] : [BIGINT]) - [11]
20:04:43,832 TRACE BasicExtractor:61 - extracted value ([collecti1_2_1_] : [BIGINT]) - [11]
20:04:43,833 TRACE BasicExtractor:61 - extracted value ([book_id1_0_2_] : [BIGINT]) - [1]
20:04:43,839 TRACE BasicExtractor:61 - extracted value ([classifi2_1_0_] : [VARCHAR]) - [Prueba]
20:04:43,841 TRACE BasicExtractor:61 - extracted value ([collecti2_2_1_] : [VARCHAR]) - [Prueba]
20:04:43,841 TRACE BasicExtractor:61 - extracted value ([book_tit2_0_2_] : [LONGVARCHAR]) - [Libro de Prueba (No Existe) ]
20:04:43,842 TRACE BasicExtractor:61 - extracted value ([book_aut3_0_2_] : [LONGVARCHAR]) - [Jonathan Pichardo]
20:04:43,842 TRACE BasicExtractor:61 - extracted value ([book_sys4_0_2_] : [BIGINT]) - [190996]
java.lang.ArrayIndexOutOfBoundsException: 57
at com.mysql.cj.mysqla.MysqlaUtils.bitToLong(MysqlaUtils.java:68)
at com.mysql.cj.core.io.MysqlTextValueDecoder.decodeBit(MysqlTextValueDecoder.java:231)
at com.mysql.cj.jdbc.ResultSetRow.decodeAndCreateReturnValue(ResultSetRow.java:170)
at com.mysql.cj.jdbc.ResultSetRow.getValueFromBytes(ResultSetRow.java:269)
at com.mysql.cj.jdbc.BufferRow.getValue(BufferRow.java:349)
at com.mysql.cj.jdbc.ResultSetImpl.getNonStringValueFromRow(ResultSetImpl.java:813)
at com.mysql.cj.jdbc.ResultSetImpl.getBoolean(ResultSetImpl.java:904)
at com.mysql.cj.jdbc.ResultSetImpl.getBoolean(ResultSetImpl.java:908)
at org.hibernate.type.descriptor.sql.BooleanTypeDescriptor$2.doExtract(BooleanTypeDescriptor.java:59)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
etc etc etc
The code I'm running is:
Session session = SessionFactoryHandler.buildIfNeeded().
openSession();
Criteria crit = session.createCriteria( Book.class );
crit.list();
session.close();
SessionFactoryHandler.closeFactory();
As I understand it is happening on the status property I just don't know why, if I comment the mapping property in the xml it works perfectly but with it it throws always the same exception with the same index 57, it doesn't make a difference the value of that column in the database (which has only one registry).
The mapping file is like follows:
<hibernate-mapping package="com.cetys.librarymanagement">
<class name="com.cetys.librarymanagement.Core.DomainModels.Book" table="book">
<meta attribute="class-description">
This class contains the whole description of a Book,
according to the specification in ALTAIR system.
</meta>
<id name="id" type="long" column="book_id">
</id>
<property name="title" column="book_title" type="text" length="500" not-null="true"/>
<property name="author" column="book_author" type="text" not-null="true"/>
<property name="systemId" column="book_system_id" type="long" not-null="true"/>
<property name="status" column="book_status" type="boolean" not-null="true"/>
<property name="fullClassification" column="book_full_classification"
type="string" not-null="true"/>
<many-to-one name="classification" column="classification_id"
class="com.cetys.librarymanagement.Core.DomainModels.Classification" not-null="true"
unique="false" cascade="save-update" fetch="join"/>
<many-to-one name="collection" column="collection_id"
class="com.cetys.librarymanagement.Core.DomainModels.Collection" not-null="false"
unique="false" cascade="save-update" fetch="join"/>
</class>
</hibernate-mapping>
Any ideas?
From what I see you are trying to map the BIT type in Database to Boolean in your hibernate code.
There is a bug in MySQL with BIT Value, from version 5.0.3 onwards, in that it does not store a single BIT value. It stores something like SET or ENUM. And that often throws up issues, when you are doing a numeric value comparison. For more details check here
http://www.xaprb.com/blog/2006/04/11/bit-values-in-mysql/
You could ask your DBA to change the datatype to tinyint, however if that is not possible, you can change the status mapping from boolean to numeric_boolean, so would be something like
<property name="status" column="book_status" type="numeric_boolean" not-null="true"/>
There are two ways you can achieve the type conversion of attribute
By annotating field with Type
#Type(type = "yes_no")
private boolean isActive;
in DB Y/N will get persisted.
By writing a converter
#Column
#Convert(converter = BooleanConverter.class)
private boolean isActive;
Converter class
public class BooleanConverter implements AttributeConverter<Boolean, Character> {
#Override
public Character convertToDatabaseColumn(Boolean attribute) {
if (attribute)
return 'Y';
else
return 'N';
}
#Override
public Boolean convertToEntityAttribute(Character dbData) {
if ('Y' == dbData)
return true;
else
return false;
}
}
in xml you can replace the type attribute with the converter class name or yes_no
<property name="status" column="book_status" type="yes_no" not-null="true"/>
Is it possible to have Oracle type object as an output from a stored procedure, calling same using spring integration?
For example, I have the following in the database:
create or replace TYPE ESP_TRAINING_REQ_OBJ AS OBJECT
(
v_param1 varchar2(25),
v_param2 varchar2(25)
);
create or replace TYPE ESP_TRAINING_RESP_OBJ AS OBJECT
(
v_param1 varchar2(25),
v_param2 varchar2(25)
);
create or replace PROCEDURE TEST_PROC (
v_req_obj IN ESP_TRAINING_REQ_OBJ,
v_resp_obj OUT ESP_TRAINING_RESP_OBJ
) AS
BEGIN
v_resp_obj := ESP_TRAINING_RESP_OBJ(v_req_obj.v_param2, v_req_obj.v_param1);
dbms_output.put_line('TEST_PROC');
END;
However, when I try calling it, I'm getting the following exception:
PLS-00306: wrong number or types of arguments in call to 'TEST_PROC'
Please find spring integration configuration bellow:
<int-jdbc:stored-proc-outbound-gateway
id="ESP_TRAINING" request-channel="inputChannel"
stored-procedure-name="TEST_PROC" data-source="dataSource"
reply-channel="outputChannel"
skip-undeclared-results="false" ignore-column-meta-data="true">
<int-jdbc:sql-parameter-definition name="v_req_obj" direction="IN" type="STRUCT" />
<int-jdbc:sql-parameter-definition name="v_resp_obj" direction="OUT" type="STRUCT" />
<int-jdbc:parameter name="v_req_obj" expression="payload.v_req_obj"/>
</int-jdbc:stored-proc-outbound-gateway>
Please note it works fine if we change SP declaration above, for using STRUCT in request only, for example replacing ESP_TRAINING_RESP_OBJ by a VARCHAR or any other Oracle primitive data type.
For Example:
create or replace PROCEDURE TEST_PROC (
v_req_obj IN ESP_TRAINING_REQ_OBJ,
v_status OUT VARCHAR2
) AS
BEGIN
v_status := v_req_obj.v_param1 || ' and ' || v_req_obj.v_param2;
dbms_output.put_line('TEST_PROC');
END;
I've fixed it doing following:
Updated spring integration version to 3.0.0.RELEASE,
giving support to both type-name and return-type attribues, inside sql-parameter-definition.
Updated stored procedured declaration as follows:
<int-jdbc:stored-proc-outbound-gateway
id="ESP_TRAINING" request-channel="inputChannel"
stored-procedure-name="TEST_PROC" data-source="dataSource"
reply-channel="outputChannel"
skip-undeclared-results="false" ignore-column-meta-data="true">
<int-jdbc:sql-parameter-definition name="v_req_obj" direction="IN" type="STRUCT" />
<int-jdbc:sql-parameter-definition name="v_resp_obj" direction="OUT" type="STRUCT" type-name="ESP_TRAINING_RESP_OBJ" return-type="espTrainingRespObj" />
<int-jdbc:parameter name="v_req_obj" expression="payload.v_req_obj"/>
</int-jdbc:stored-proc-outbound-gateway>
<beans:bean id="espTrainingRespObj" class="com.hsbc.esp.EspTrainingRespObj"/>
Changed EspTrainingRespObj to implement SQLReturnType, as follows:
public class EspTrainingRespObj implements SqlReturnType {
private String param1;
private String param2;
public Object getTypeValue(CallableStatement cs, int paramIndex, int sqlType, String typeName)
throws SQLException {
Object[] attributes = ((STRUCT) cs.getObject(paramIndex)).getAttributes();
this.param1 = (String) attributes[0];
this.param2 = (String) attributes[1];
return this;
}
...
}
The return-type on the <int-jdbc:sql-parameter-definition> for OUT param and SqlReturnStruct must help you to solve the issue.
The test-case in the Framework source codes contains this sample for CLOB handling:
<int-jdbc:stored-proc-outbound-gateway request-channel="getMessageChannel"
data-source="dataSource"
stored-procedure-name="GET_MESSAGE"
ignore-column-meta-data="true"
expect-single-result="true"
reply-channel="output2Channel">
<int-jdbc:sql-parameter-definition name="message_id"/>
<int-jdbc:sql-parameter-definition name="message_json" type="CLOB" direction="OUT" type-name="" return-type="clobSqlReturnType"/>
<int-jdbc:parameter name="message_id" expression="payload"/>
</int-jdbc:stored-proc-outbound-gateway>
<bean id="clobSqlReturnType" class="org.mockito.Mockito" factory-method="spy">
<constructor-arg>
<bean class="org.springframework.integration.jdbc.storedproc.ClobSqlReturnType"/>
</constructor-arg>
</bean>
I am migrating an application from Oracle 10g to Oracle 11g and i am having trouble on a method included on a "OSubjectsqlmapdao" (the application uses ibatis 2).
public List retrieveList(String user, String flag)throws Exception
{
try{
logger.info("Retreving List");
java.sql.ResultSet rs = null;
Map map = new HashMap();
map.put("user",user);
map.put("flag",flag);
map.put("listRetrieved",null);
List listRetrieved = new ArrayList();
queryForObject("DBListRetrieved",map);
rs = (java.sql.ResultSet)map.get("listRetrieved");
logger.info("HAsmap map " + map.size());
logger.info("HAsmap map " + map.isEmpty());
logger.info("listRetrieved map " + map.get("listRetrieved "));
logger.info("listRetrieved map getClass" + map.get("listRetrieved ").getClass());
OSubject subject = null;
while (rs.next())
{
subject = new OAsuntos();
subject.setUser(rs.getString(1));
subject.setCdode(rs.getString(2));
subject.setDescrip(rs.getString(3));
listRetrieved .add(subject );
}
return listRetrieved ;
}catch(Exception e){
logger.error(e.getMessage());
throw new Exception (e.getMessage());
}
}
The OSubject .xml is defined as following:
<parameterMap id="parameterMapRetrieveList" class="map">
<parameter property="listRetrieved" javaType="java.lang.Object" jdbcType="ORACLECURSOR" mode="OUT"/>
<parameter property="user" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
<parameter property="flag" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
</parameterMap>
<procedure id="DBListRetrieved" parameterMap="parameterMapRetrieveList">
{ ? = call AS.PCK_LIST.F_RetrieveList(?,?)}
</procedure>
The method worked perfectly in Oracle 10g but it does not work after the migration of the DDBB. Besides, the map list class is according to the log oracle.jdbc.driver when i am not using that driver and i think is not being referenced or even exist on the application.
The Log trace is:
Retreving List 2014-06-25 14:54:55,098 INFO OSubjectSqlMapDao
(OSubjectSqlMapDao .java:1268) - HAsmap map 3 2014-06-25 14:54:55,099
INFO OSubjectSqlMapDao (OSubjectSqlMapDao .java:1270) - HAsmap map
false 2014-06-25 14:54:55,099 INFO OSubjectSqlMapDao
(OSubjectSqlMapDao .java:1273) - listRetrieved map
oracle.jdbc.driver.OracleResultSetImpl#4efd9ac2 2014-06-25
14:54:55,100 INFO OSubjectSqlMapDao (OSubjectSqlMapDao .java:1276)
- listRetrieved map getClassclass oracle.jdbc.driver.OracleResultSetImpl 2014-06-25 14:54:55,104 ERROR
OSubjectSqlMapDao (OSubjectSqlMapDao .java:1294) - Closed Statement:
next
It would be very helpful if someone could lend me a hand. Thanks in advance.
I'm trying to register a custom dialect in Hibernate. I found a ton of examples, and I thought I had it - and now it tells me that the function does not exist in my database. Specifically, I'm trying to create the date_add() dialect for MySQL 5.6. I'm using hibernate 3.6.7.
In hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="dialect">com.myPackage.CustomMySQLDialect</property>
</session-factory>
</hibernate-configuration>
In com.myPackage.CustomMySQLDialect:
public class CustomMySQLDialect extends MySQL5InnoDBDialect {
public CustomMySQLDialect() {
super();
registerFunction( "date_add_interval", new SQLFunctionTemplate( Hibernate.DATE, "date_add(?1, interval ?2 ?3)" ) );
}
}
And when I go to call it in the DAOImpl class:
List<User> userList = null;
Query confirmationUser = session.getCurrentSession().createQuery("from InitUser where enabled = 0 and date_add_interval(created_date, 1, day) < now() and end_date is null");
userList = confirmationUser.list(); // <-- this is where it dies
Here's the exception:
Hibernate: select inituser0_.init_user_id as init1_58_, inituser0_.confirmation_date as confirma2_58_, inituser0_.confirmation_sent_date as confirma3_58_, inituser0_.confirmation_token as confirma4_58_, inituser0_.created_date as created5_58_, inituser0_.current_sign_in_date as current6_58_, inituser0_.current_sign_in_ip as current7_58_, inituser0_.email as email58_, inituser0_.enabled as enabled58_, inituser0_.end_date as end10_58_, inituser0_.failed_sign_in_count as failed11_58_, inituser0_.last_sign_in_date as last12_58_, inituser0_.last_sign_in_ip as last13_58_, inituser0_.password as password58_, inituser0_.remember_created_date as remember15_58_, inituser0_.reset_password_confirmation_date as reset16_58_, inituser0_.reset_password_sent_date as reset17_58_, inituser0_.reset_password_token as reset18_58_, inituser0_.sign_in_count as sign19_58_, inituser0_.updated_by as updated20_58_, inituser0_.updated_date as updated21_58_, inituser0_.username as username58_ from InitUser inituser0_ where inituser0_.end_date is null
Hibernate: select inituser0_.init_user_id as init1_58_, inituser0_.confirmation_date as confirma2_58_, inituser0_.confirmation_sent_date as confirma3_58_, inituser0_.confirmation_token as confirma4_58_, inituser0_.created_date as created5_58_, inituser0_.current_sign_in_date as current6_58_, inituser0_.current_sign_in_ip as current7_58_, inituser0_.email as email58_, inituser0_.enabled as enabled58_, inituser0_.end_date as end10_58_, inituser0_.failed_sign_in_count as failed11_58_, inituser0_.last_sign_in_date as last12_58_, inituser0_.last_sign_in_ip as last13_58_, inituser0_.password as password58_, inituser0_.remember_created_date as remember15_58_, inituser0_.reset_password_confirmation_date as reset16_58_, inituser0_.reset_password_sent_date as reset17_58_, inituser0_.reset_password_token as reset18_58_, inituser0_.sign_in_count as sign19_58_, inituser0_.updated_by as updated20_58_, inituser0_.updated_date as updated21_58_, inituser0_.username as username58_ from InitUser inituser0_ where inituser0_.enabled=0 and date_add_interval(inituser0_.created_date, 1, day)<now() and (inituser0_.end_date is null)
WARN : org.hibernate.util.JDBCExceptionReporter - SQL Error: 1305, SQLState: 42000
ERROR: org.hibernate.util.JDBCExceptionReporter - FUNCTION myDBName.date_add_interval does not exist
ERROR: com.somePackage.InitUserDAOImpl - could not execute query
It gets beyond the creation of the query, and then tries to execute it, and then complains it can't find that function. It specifies the name of my database in the prefix to the database name.
Is this not being registered correctly? Should I specify myDBName as the database to register? If so, how?
Or am I way off?
In the end, I used Joda for the time calculation and sent it in pre-calculated. On the one hand, I had to re-do a bunch of code to support this. On the other, I've been using it ever sense and couldn't be happier.
http://www.joda.org/joda-time/