I am trying to lambda expression in Spring data JDBC jdbcTemplate.query method, but getting below error.
The method query(String, ResultSetExtractor) in the type JdbcTemplate is not applicable for the arguments (String, ( rs, rowNumber) -> {})
Code
#Override
public List<Course> list() {
String sql = "select cr.courseId,cr.title,cr.credit,cr.courseMaterialId, cm.url from course_jdbc_tb cr, coursematerial_jdbc_tb cm where cr.courseMaterialId=cm.courseMaterialId";
return jdbcTemplate.query(sql, (rs, rowNumber) -> {
Course course = new Course();
CourseMaterial courseMaterial = new CourseMaterial();
courseMaterial.setCourseMaterialId(rs.getLong("courseMaterialId"));
courseMaterial.setUrl(rs.getString("url"));
course.setCourseId(rs.getInt("courseId"));
course.setTitle(rs.getString("title"));
course.setCredit(rs.getInt("credit"));
course.setCourseMaterial(courseMaterial);
});
}[![error and code][1]][1]
Related
I have created an H2 alias function which is being called when I execute the corresponding spring jdbc StoredProcedure.
public static ResultSet dao_cashflow_read(Integer contractId, Integer contractVersion, Date rateDtmDate, String refSrc,
String rateStatus, String rateType, String message, Integer rowCount) throws SQLException, IOException {
File f = new File(FixingDaoIT.class.getResource("/").getFile().concat("csv/ldn/fixing.csv"));
return new Csv().read(new FileReader(f), null);
}
This part is working as expected as the associated row mapper function parses the result set correctly and generates the entity objects. The problem is, the JdbcTemplate class then attempts to extract the associated output parameters that were registered with the StoredProcedure implementation. Which in turn calls the method below in class JdbcCallableStatement.java
private JdbcResultSet getOpenResultSet() throws SQLException {
try {
checkClosed();
if (resultSet == null) {
throw DbException.get(ErrorCode.NO_DATA_AVAILABLE);
}
if (resultSet.isBeforeFirst()) {
resultSet.next();
}
return resultSet;
} catch (Exception e) {
throw logAndConvert(e);
}
}
This call fails as the resultSet reference is now null and it throws the DbException NO_DATA_AVAILBLE
If I run the application against Sybase, the output params are as expected. Is this an issue with H2 not supporting output params?
I am using Spring and stored procedures to retrieve data from a mySQL database. I have the stored procedure and parameters working OK but I'm having problems mapping the result set. At the moment I have some truly ugly code to get the values and I'm sure there has to be a better, cleaner and more elegant way. Can anyone guide me to a better solution?
After the stored procedure class, I have:
List<String> outList = new ArrayList<String>();
Map<String,Object> outMap = execute(parameters_map);
List list = (List) outMap.get("#result-set-1");
for (Object object : list) {
Map map2 = (Map) object;
list.add(map2.get("runname"));
}
return outList;
runname is the column from the database query.
Is there a better way to achieve this?
Example from spring docs using RowMapper:
public class JdbcActorDao implements ActorDao {
private SimpleJdbcCall procReadAllActors;
public void setDataSource(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.setResultsMapCaseInsensitive(true);
this.procReadAllActors = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("read_all_actors")
.returningResultSet("actors",
BeanPropertyRowMapper.newInstance(Actor.class));
}
public List getActorsList() {
Map m = procReadAllActors.execute(new HashMap<String, Object>(0));
return (List) m.get("actors");
}
// ... additional methods
}
took a while to interpret the Spring docs but I finally got there.
My solution:
SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("DistinctRunNames")
.withoutProcedureColumnMetaDataAccess();
simpleJdbcCall.addDeclaredParameter(new SqlParameter("environment", Types.VARCHAR));
simpleJdbcCall.addDeclaredParameter(new SqlParameter("username", Types.VARCHAR));
simpleJdbcCall.addDeclaredParameter(new SqlParameter("test_suite", Types.VARCHAR));
SqlParameterSource parameters = new MapSqlParameterSource().addValue("environment", environment)
.addValue("username", username).addValue("test_suite", testSuite);
Map map = simpleJdbcCall.returningResultSet("runnames", new ParameterizedRowMapper<RunNameBean>() {
public RunNameBean mapRow(ResultSet rs, int rowNum) throws SQLException {
RunNameBean runNameBean = new RunNameBean();
runNameBean.setName(rs.getString("runname"));
return runNameBean;
}
}).execute(parameters);
return (List) map.get("runnames");
Had problems with expected parameters versus actual, had to break up the simpleJdbcCall object. Maps the results into a list beautifully.
Thank you for answers, helped me to learn about Spring mapping.
I am using queryForList to get a list from DB ,
my code looks like,
List<RoleIdBean> role = jdbcTemplate.queryForList(query , new Object[] {userId},RoleIdBean.class);
query = select * from role where userid=?
role table has two coloumns and roleIdBean has two variables .
When I am running this code it is saying expected 1, actual 2
Could someone please check where i am going wrong and assist how to use this method.
As M. Deinum mentions, you have to provide implementation of RowMapper interface so that Spring knows which columns from your table to map to which properties of your object (RoleIdBean). For instance like this:
List<RoleIdBean> list = jdbcTemplate.query("SELECT * FROM role_id", new Object[]{ userId }, new RowMapper<RoleIdBean>() {
#Override
public RoleIdBean mapRow(ResultSet rs, int rowNum) throws SQLException {
RoleIdBean bean = new RoleIdBean();
// Set properties from the ResultSet, e.g:
// bean.setRole(rs.getString(1));
return bean;
}
});
I'm using Spring and Oracle database in my solution and i need to execute script
select count(1) from ELEMENTS, table(cast(? as arrayofnumbers)) session_ids
where root_session_id in session_ids.VALUE
but i have a problem with passing input parameter.
i try to pass List or array of BigInteger into
JdbcTemplate.queryForObject("select count(1) from ELEMENTS, table(cast(? as arrayofnumbers)) session_ids
where root_session_id in session_ids.VALUE", Integer.class, INPUT_PARAMS)
but has an Exception:
java.sql.SQLException: Invalid column type
at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8861)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8338)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9116)
at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:9093)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:234)
at weblogic.jdbc.wrapper.PreparedStatement.setObject(PreparedStatement.java:357)
Does anyone have the same problem?
EDIT:
Forget to describe arrayofnumber. It's custom type:
TYPE arrayofnumbers as table of number(20)
Found the solution:
final BigInteger[] ids = new BigInteger[]{BigInteger.valueOf(9137797712513092132L)};
int count = jdbc.query("select count(1) from NC_DATAFLOW_ELEMENTS\n" +
" where root_session_id in (select /*+ cardinality(t 10) */ * from table(cast (? as arrayofnumbers)) t)"
, new PreparedStatementSetter() {
public void setValues(PreparedStatement preparedStatement) throws SQLException {
Connection conn = preparedStatement.getConnection();
OracleConnection oraConn = conn.unwrap(OracleConnection.class);
oracle.sql.ARRAY widgets = oraConn.createARRAY("ARRAYOFNUMBERS", ids);
preparedStatement.setArray(1, widgets);
}
}, new ResultSetExtractor<Integer>() {
public Integer extractData(ResultSet resultSet) throws SQLException, DataAccessException {
resultSet.next();
return resultSet.getInt(1);
}
});
out.println(count);
should note that type of array (ARRAYOFNUMBER) should be in upper case
I use the Spring JDBCTemplate to call a stored procedure ,like this
Map receive10PrmtBill = (Map) getJdbcTemplate().execute(sql, new CallableStatementCallback() {
#Override
public Object doInCallableStatement(CallableStatement cs) throws SQLException,
DataAccessException {
cs.setString(1, Constants.ADD_PROC_TYPE);
Map<String,PrmtBillInfoDatagram> tempMap = new HashMap();
cs.execute();
but the execute method return false and didn't throw any exception ,so I don't know what's wrong with my program , how to catch the Exception? Any help?
This is the proc
create proc sp_xx ( #userid int)
as
begin
select personid, personname from person where personid = #userid
select teamid, teamname from team
end
Try setting "IGNORE_DONE_IN_PROC" property to "true". See at:
http://javabob64.wordpress.com/2011/04/12/sybase-and-the-jdbc-driver/