JdbcTemplateTestSuite.java
Upload User: jiancairen
Upload Date: 2007-08-27
Package Size: 26458k
Code Size: 59k
Category:

Java Develop

Development Platform:

Java

  1. /*
  2.  * Copyright 2002-2004 the original author or authors.
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */ 
  16. package org.springframework.jdbc.core;
  17. import java.sql.CallableStatement;
  18. import java.sql.Connection;
  19. import java.sql.DatabaseMetaData;
  20. import java.sql.PreparedStatement;
  21. import java.sql.ResultSet;
  22. import java.sql.ResultSetMetaData;
  23. import java.sql.SQLException;
  24. import java.sql.SQLWarning;
  25. import java.sql.Statement;
  26. import java.util.ArrayList;
  27. import java.util.LinkedList;
  28. import java.util.List;
  29. import java.util.Map;
  30. import javax.sql.DataSource;
  31. import org.easymock.MockControl;
  32. import org.springframework.dao.DataAccessException;
  33. import org.springframework.dao.InvalidDataAccessApiUsageException;
  34. import org.springframework.dao.UncategorizedDataAccessException;
  35. import org.springframework.jdbc.AbstractJdbcTests;
  36. import org.springframework.jdbc.BadSqlGrammarException;
  37. import org.springframework.jdbc.CannotGetJdbcConnectionException;
  38. import org.springframework.jdbc.SQLWarningException;
  39. import org.springframework.jdbc.UncategorizedSQLException;
  40. import org.springframework.jdbc.datasource.SingleConnectionDataSource;
  41. import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
  42. import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
  43. import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
  44. /** 
  45.  * Mock object based tests for JdbcTemplate.
  46.  * @author Rod Johnson
  47.  */
  48. public class JdbcTemplateTestSuite extends AbstractJdbcTests {
  49. public void testBeanProperties() throws Exception {
  50. replay();
  51. JdbcTemplate t = new JdbcTemplate(mockDataSource);
  52. assertTrue("datasource ok", t.getDataSource() == mockDataSource);
  53. assertTrue("ignores warnings by default", t.getIgnoreWarnings());
  54. t.setIgnoreWarnings(false);
  55. assertTrue("can set NOT to ignore warnings", !t.getIgnoreWarnings());
  56. }
  57. public void testCannotRunStaticSqlWithBindParameters() throws Exception {
  58. final String sql = "UPDATE FOO SET NAME='tony' WHERE ID > ?";
  59. replay();
  60. JdbcTemplate t = new JdbcTemplate(mockDataSource);
  61. try {
  62. t.query(sql, new RowCountCallbackHandler());
  63. fail("Should have objected to bind variables");
  64. }
  65. catch (InvalidDataAccessApiUsageException ex) {
  66. // Ok 
  67. }
  68. }
  69. public void testUpdateCount() throws Exception {
  70. final String sql =
  71. "UPDATE INVOICE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
  72. int idParam = 11111;
  73. MockControl ctrlPreparedStatement =
  74. MockControl.createControl(PreparedStatement.class);
  75. PreparedStatement mockPreparedStatement =
  76. (PreparedStatement) ctrlPreparedStatement.getMock();
  77. mockPreparedStatement.setInt(1, idParam);
  78. ctrlPreparedStatement.setVoidCallable();
  79. mockPreparedStatement.executeUpdate();
  80. ctrlPreparedStatement.setReturnValue(1);
  81. mockPreparedStatement.getWarnings();
  82. ctrlPreparedStatement.setReturnValue(null);
  83. mockPreparedStatement.close();
  84. ctrlPreparedStatement.setVoidCallable();
  85. mockConnection.prepareStatement(sql);
  86. ctrlConnection.setReturnValue(mockPreparedStatement);
  87. ctrlPreparedStatement.replay();
  88. replay();
  89. Dispatcher d = new Dispatcher(idParam, sql);
  90. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  91. int rowsAffected = template.update(d);
  92. assertTrue("1 update affected 1 row", rowsAffected == 1);
  93. /*
  94. d = new Dispatcher(idParam);
  95. rowsAffected = template.update(d);
  96. assertTrue("bogus update affected 0 rows", rowsAffected == 0);
  97. */
  98. ctrlPreparedStatement.verify();
  99. }
  100. public void testBogusUpdate() throws Exception {
  101. final String sql =
  102. "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
  103. final int idParam = 6666;
  104. // It's because Integers aren't canonical
  105. SQLException sex = new SQLException("bad update");
  106. MockControl ctrlPreparedStatement =
  107. MockControl.createControl(PreparedStatement.class);
  108. PreparedStatement mockPreparedStatement =
  109. (PreparedStatement) ctrlPreparedStatement.getMock();
  110. mockPreparedStatement.setInt(1, idParam);
  111. ctrlPreparedStatement.setVoidCallable();
  112. mockPreparedStatement.executeUpdate();
  113. ctrlPreparedStatement.setThrowable(sex);
  114. mockPreparedStatement.close();
  115. ctrlPreparedStatement.setVoidCallable();
  116. mockConnection.prepareStatement(sql);
  117. ctrlConnection.setReturnValue(mockPreparedStatement);
  118. ctrlPreparedStatement.replay();
  119. replay();
  120. Dispatcher d = new Dispatcher(idParam, sql);
  121. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  122. try {
  123. template.update(d);
  124. fail("Bogus update should throw exception");
  125. }
  126. catch (UncategorizedDataAccessException ex) {
  127. // pass
  128. assertTrue(
  129. "Correct exception",
  130. ex instanceof UncategorizedSQLException);
  131. assertTrue("Root cause is correct", ex.getCause() == sex);
  132. //assertTrue("no update occurred", !je.getDataWasUpdated());
  133. }
  134. ctrlPreparedStatement.verify();
  135. }
  136. public void testStringsWithStaticSql() throws Exception {
  137. doTestStrings(new JdbcTemplateCallback() {
  138. public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
  139. template.query(sql, rch);
  140. }
  141. }, false, null);
  142. }
  143. public void testStringsWithEmptyPreparedStatementSetter() throws Exception {
  144. doTestStrings(new JdbcTemplateCallback() {
  145. public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
  146. template.query(sql, (PreparedStatementSetter) null, rch);
  147. }
  148. }, true, null);
  149. }
  150. public void testStringsWithPreparedStatementSetter() throws Exception {
  151. final Integer argument = new Integer(99);
  152. doTestStrings(new JdbcTemplateCallback() {
  153. public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
  154. template.query(sql, new PreparedStatementSetter() {
  155. public void setValues(PreparedStatement ps) throws SQLException {
  156. ps.setObject(1, argument);
  157. }
  158. }, rch);
  159. }
  160. }, true, argument);
  161. }
  162. public void testStringsWithEmptyPreparedStatementArgs() throws Exception {
  163. doTestStrings(new JdbcTemplateCallback() {
  164. public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
  165. template.query(sql, (Object[]) null, rch);
  166. }
  167. }, true, null);
  168. }
  169. public void testStringsWithPreparedStatementArgs() throws Exception {
  170. final Integer argument = new Integer(99);
  171. doTestStrings(new JdbcTemplateCallback() {
  172. public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) {
  173. template.query(sql, new Object[] {argument}, rch);
  174. }
  175. }, true, argument);
  176. }
  177. protected void doTestStrings(JdbcTemplateCallback jdbcTemplateCallback,
  178.                              boolean usePreparedStatement, Object argument) throws Exception {
  179. String sql = "SELECT FORENAME FROM CUSTMR";
  180. String[] results = { "rod", "gary", " portia" };
  181. class StringHandler implements RowCallbackHandler {
  182. private List l = new LinkedList();
  183. public void processRow(ResultSet rs) throws SQLException {
  184. l.add(rs.getString(1));
  185. }
  186. public String[] getStrings() {
  187. return (String[]) l.toArray(new String[l.size()]);
  188. }
  189. }
  190. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  191. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  192. mockResultSet.next();
  193. ctrlResultSet.setReturnValue(true);
  194. mockResultSet.getString(1);
  195. ctrlResultSet.setReturnValue(results[0]);
  196. mockResultSet.next();
  197. ctrlResultSet.setReturnValue(true);
  198. mockResultSet.getString(1);
  199. ctrlResultSet.setReturnValue(results[1]);
  200. mockResultSet.next();
  201. ctrlResultSet.setReturnValue(true);
  202. mockResultSet.getString(1);
  203. ctrlResultSet.setReturnValue(results[2]);
  204. mockResultSet.next();
  205. ctrlResultSet.setReturnValue(false);
  206. mockResultSet.close();
  207. ctrlResultSet.setVoidCallable();
  208. MockControl ctrlStatement =
  209. MockControl.createControl(PreparedStatement.class);
  210. PreparedStatement mockStatement =
  211. (PreparedStatement) ctrlStatement.getMock();
  212. if (argument != null) {
  213. mockStatement.setObject(1, argument);
  214. }
  215. if (usePreparedStatement) {
  216. mockStatement.executeQuery();
  217. }
  218. else {
  219. mockStatement.executeQuery(sql);
  220. }
  221. ctrlStatement.setReturnValue(mockResultSet);
  222. mockStatement.getWarnings();
  223. ctrlStatement.setReturnValue(null);
  224. mockStatement.close();
  225. ctrlStatement.setVoidCallable();
  226. if (usePreparedStatement) {
  227. mockConnection.prepareStatement(sql);
  228. }
  229. else {
  230. mockConnection.createStatement();
  231. }
  232. ctrlConnection.setReturnValue(mockStatement);
  233. ctrlResultSet.replay();
  234. ctrlStatement.replay();
  235. replay();
  236. StringHandler sh = new StringHandler();
  237. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  238. jdbcTemplateCallback.doInJdbcTemplate(template, sql, sh);
  239. // Match
  240. String[] forenames = sh.getStrings();
  241. assertTrue("same length", forenames.length == results.length);
  242. for (int i = 0; i < forenames.length; i++) {
  243. assertTrue("Row " + i + " matches", forenames[i].equals(results[i]));
  244. }
  245. ctrlResultSet.verify();
  246. ctrlStatement.verify();
  247. }
  248. public void testLeaveConnOpenOnRequest() throws Exception {
  249. String sql = "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3";
  250. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  251. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  252. ctrlResultSet = MockControl.createControl(ResultSet.class);
  253. mockResultSet = (ResultSet) ctrlResultSet.getMock();
  254. mockResultSet.next();
  255. ctrlResultSet.setReturnValue(false);
  256. mockResultSet.close();
  257. ctrlResultSet.setVoidCallable();
  258. MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
  259. PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
  260. ctrlStatement = MockControl.createControl(PreparedStatement.class);
  261. mockStatement = (PreparedStatement) ctrlStatement.getMock();
  262. mockStatement.executeQuery(sql);
  263. ctrlStatement.setReturnValue(mockResultSet);
  264. mockStatement.getWarnings();
  265. ctrlStatement.setReturnValue(null);
  266. mockStatement.close();
  267. ctrlStatement.setVoidCallable();
  268. mockConnection.isClosed();
  269. ctrlConnection.setReturnValue(false, 2);
  270. mockConnection.createStatement();
  271. ctrlConnection.setReturnValue(mockStatement);
  272. // if close is called entire test will fail
  273. mockConnection.close();
  274. ctrlConnection.setDefaultThrowable(new RuntimeException());
  275. ctrlResultSet.replay();
  276. ctrlStatement.replay();
  277. replay();
  278. SingleConnectionDataSource scf = new SingleConnectionDataSource(mockDataSource.getConnection(), false);
  279. JdbcTemplate template2 = new JdbcTemplate(scf);
  280. RowCountCallbackHandler rcch = new RowCountCallbackHandler();
  281. template2.query(sql, rcch);
  282. ctrlResultSet.verify();
  283. ctrlStatement.verify();
  284. }
  285. public void testCloseConnOnRequest() throws Exception {
  286. String sql = "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3";
  287. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  288. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  289. mockResultSet.next();
  290. ctrlResultSet.setReturnValue(false);
  291. mockResultSet.close();
  292. ctrlResultSet.setVoidCallable();
  293. MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
  294. PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
  295. mockStatement.executeQuery(sql);
  296. ctrlStatement.setReturnValue(mockResultSet);
  297. mockStatement.getWarnings();
  298. ctrlStatement.setReturnValue(null);
  299. mockStatement.close();
  300. ctrlStatement.setVoidCallable();
  301. mockConnection.createStatement();
  302. ctrlConnection.setReturnValue(mockStatement);
  303. ctrlResultSet.replay();
  304. ctrlStatement.replay();
  305. replay();
  306. JdbcTemplate template2 = new JdbcTemplate(mockDataSource);
  307. RowCountCallbackHandler rcch = new RowCountCallbackHandler();
  308. template2.query(sql, rcch);
  309. ctrlResultSet.verify();
  310. ctrlStatement.verify();
  311. }
  312. /**
  313.  * Test that we see a runtime exception come back.
  314.  */
  315. public void testExceptionComesBack() throws Exception {
  316. final String sql = "SELECT ID FROM CUSTMR";
  317. final RuntimeException rex = new RuntimeException("What I want to see");
  318. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  319. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  320. mockResultSet.next();
  321. ctrlResultSet.setReturnValue(true);
  322. mockResultSet.close();
  323. ctrlResultSet.setVoidCallable();
  324. MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
  325. PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
  326. mockStatement.executeQuery(sql);
  327. ctrlStatement.setReturnValue(mockResultSet);
  328. mockStatement.getWarnings();
  329. ctrlStatement.setReturnValue(null);
  330. mockStatement.close();
  331. ctrlStatement.setVoidCallable();
  332. mockConnection.createStatement();
  333. ctrlConnection.setReturnValue(mockStatement);
  334. ctrlResultSet.replay();
  335. ctrlStatement.replay();
  336. replay();
  337. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  338. try {
  339. template.query(sql, new RowCallbackHandler() {
  340. public void processRow(java.sql.ResultSet rs)
  341. throws java.sql.SQLException {
  342. throw rex;
  343. }
  344. });
  345. fail("Should have thrown exception");
  346. }
  347. catch (RuntimeException ex) {
  348. assertTrue("Wanted same exception back, not " + ex, ex == rex);
  349. }
  350. }
  351. /**
  352.  * Test update with static SQL.
  353.  */
  354. public void testSqlUpdate() throws Exception {
  355. final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 4";
  356. int rowsAffected = 33;
  357. MockControl ctrlStatement = MockControl.createControl(Statement.class);
  358. Statement mockStatement = (Statement) ctrlStatement.getMock();
  359. mockStatement.executeUpdate(sql);
  360. ctrlStatement.setReturnValue(rowsAffected);
  361. mockStatement.getWarnings();
  362. ctrlStatement.setReturnValue(null);
  363. mockStatement.close();
  364. ctrlStatement.setVoidCallable();
  365. mockConnection.createStatement();
  366. ctrlConnection.setReturnValue(mockStatement);
  367. ctrlStatement.replay();
  368. replay();
  369. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  370. int actualRowsAffected = template.update(sql);
  371. assertTrue(
  372. "Actual rows affected is correct",
  373. actualRowsAffected == rowsAffected);
  374. ctrlStatement.verify();
  375. }
  376. public void testSqlUpdateEncountersSqlException() throws Exception {
  377. SQLException sex = new SQLException("bad update");
  378. final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 4";
  379. MockControl ctrlStatement = MockControl.createControl(Statement.class);
  380. Statement mockStatement = (Statement) ctrlStatement.getMock();
  381. mockStatement.executeUpdate(sql);
  382. ctrlStatement.setThrowable(sex);
  383. mockStatement.close();
  384. ctrlStatement.setVoidCallable();
  385. mockConnection.createStatement();
  386. ctrlConnection.setReturnValue(mockStatement);
  387. ctrlStatement.replay();
  388. replay();
  389. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  390. try {
  391. template.update(sql);
  392. }
  393. catch (DataAccessException ex) {
  394. assertTrue("root cause is correct", ex.getCause() == sex);
  395. }
  396. ctrlStatement.verify();
  397. }
  398. public void testSqlUpdateWithThreadConnection() throws Exception {
  399. final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 4";
  400. int rowsAffected = 33;
  401. MockControl ctrlStatement = MockControl.createControl(Statement.class);
  402. Statement mockStatement = (Statement) ctrlStatement.getMock();
  403. mockStatement.executeUpdate(sql);
  404. ctrlStatement.setReturnValue(rowsAffected);
  405. mockStatement.getWarnings();
  406. ctrlStatement.setReturnValue(null);
  407. mockStatement.close();
  408. ctrlStatement.setVoidCallable();
  409. mockConnection.createStatement();
  410. ctrlConnection.setReturnValue(mockStatement);
  411. ctrlStatement.replay();
  412. replay();
  413. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  414. int actualRowsAffected = template.update(sql);
  415. assertTrue(
  416. "Actual rows affected is correct",
  417. actualRowsAffected == rowsAffected);
  418. ctrlStatement.verify();
  419. }
  420. public void testBatchUpdate() throws Exception {
  421. final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
  422. final int[] ids = new int[] { 100, 200 };
  423. MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
  424. PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
  425. mockPreparedStatement.getConnection();
  426. ctrlPreparedStatement.setReturnValue(mockConnection);
  427. mockPreparedStatement.setInt(1, ids[0]);
  428. ctrlPreparedStatement.setVoidCallable();
  429. mockPreparedStatement.addBatch();
  430. ctrlPreparedStatement.setVoidCallable();
  431. mockPreparedStatement.setInt(1, ids[1]);
  432. ctrlPreparedStatement.setVoidCallable();
  433. mockPreparedStatement.addBatch();
  434. ctrlPreparedStatement.setVoidCallable();
  435. mockPreparedStatement.executeBatch();
  436. ctrlPreparedStatement.setReturnValue(ids);
  437. mockPreparedStatement.getWarnings();
  438. ctrlPreparedStatement.setReturnValue(null);
  439. mockPreparedStatement.close();
  440. ctrlPreparedStatement.setVoidCallable();
  441. MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class);
  442. DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock();
  443. mockDatabaseMetaData.getDatabaseProductName();
  444. ctrlDatabaseMetaData.setReturnValue("MySQL");
  445. mockDatabaseMetaData.getDriverVersion();
  446. ctrlDatabaseMetaData.setReturnValue("1.2.3");
  447. mockDatabaseMetaData.supportsBatchUpdates();
  448. ctrlDatabaseMetaData.setReturnValue(true);
  449. mockConnection.prepareStatement(sql);
  450. ctrlConnection.setReturnValue(mockPreparedStatement);
  451. mockConnection.getMetaData();
  452. ctrlConnection.setReturnValue(mockDatabaseMetaData, 2);
  453. ctrlPreparedStatement.replay();
  454. ctrlDatabaseMetaData.replay();
  455. replay();
  456. BatchPreparedStatementSetter setter =
  457. new BatchPreparedStatementSetter() {
  458. public void setValues(PreparedStatement ps, int i)
  459. throws SQLException {
  460. ps.setInt(1, ids[i]);
  461. }
  462. public int getBatchSize() {
  463. return ids.length;
  464. }
  465. };
  466. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  467. int[] actualRowsAffected = template.batchUpdate(sql, setter);
  468. assertTrue("executed 2 updates", actualRowsAffected.length == 2);
  469. ctrlPreparedStatement.verify();
  470. ctrlDatabaseMetaData.verify();
  471. }
  472. public void testBatchUpdateWithNoBatchSupport() throws Exception {
  473. final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
  474. final int[] ids = new int[] { 100, 200 };
  475. MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
  476. PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
  477. mockPreparedStatement.getConnection();
  478. ctrlPreparedStatement.setReturnValue(mockConnection);
  479. mockPreparedStatement.setInt(1, ids[0]);
  480. ctrlPreparedStatement.setVoidCallable();
  481. mockPreparedStatement.executeUpdate();
  482. ctrlPreparedStatement.setReturnValue(ids[0]);
  483. mockPreparedStatement.setInt(1, ids[1]);
  484. ctrlPreparedStatement.setVoidCallable();
  485. mockPreparedStatement.executeUpdate();
  486. ctrlPreparedStatement.setReturnValue(ids[1]);
  487. mockPreparedStatement.getWarnings();
  488. ctrlPreparedStatement.setReturnValue(null);
  489. mockPreparedStatement.close();
  490. ctrlPreparedStatement.setVoidCallable();
  491. mockConnection.prepareStatement(sql);
  492. ctrlConnection.setReturnValue(mockPreparedStatement);
  493. ctrlPreparedStatement.replay();
  494. replay();
  495. BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter() {
  496. public void setValues(PreparedStatement ps, int i) throws SQLException {
  497. ps.setInt(1, ids[i]);
  498. }
  499. public int getBatchSize() {
  500. return ids.length;
  501. }
  502. };
  503. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  504. int[] actualRowsAffected = template.batchUpdate(sql, setter);
  505. assertTrue("executed 2 updates", actualRowsAffected.length == 2);
  506. ctrlPreparedStatement.verify();
  507. }
  508. public void testBatchUpdateFails() throws Exception {
  509. final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
  510. final int[] ids = new int[] { 100, 200 };
  511. SQLException sex = new SQLException();
  512. MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
  513. PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
  514. mockPreparedStatement.getConnection();
  515. ctrlPreparedStatement.setReturnValue(mockConnection);
  516. mockPreparedStatement.setInt(1, ids[0]);
  517. ctrlPreparedStatement.setVoidCallable();
  518. mockPreparedStatement.addBatch();
  519. ctrlPreparedStatement.setVoidCallable();
  520. mockPreparedStatement.setInt(1, ids[1]);
  521. ctrlPreparedStatement.setVoidCallable();
  522. mockPreparedStatement.addBatch();
  523. ctrlPreparedStatement.setVoidCallable();
  524. mockPreparedStatement.executeBatch();
  525. ctrlPreparedStatement.setThrowable(sex);
  526. mockPreparedStatement.close();
  527. ctrlPreparedStatement.setVoidCallable();
  528. MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class);
  529. DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock();
  530. mockDatabaseMetaData.getDatabaseProductName();
  531. ctrlDatabaseMetaData.setReturnValue("MySQL");
  532. mockDatabaseMetaData.getDriverVersion();
  533. ctrlDatabaseMetaData.setReturnValue("1.2.3");
  534. mockDatabaseMetaData.supportsBatchUpdates();
  535. ctrlDatabaseMetaData.setReturnValue(true);
  536. ctrlConnection.reset();
  537. mockConnection.prepareStatement(sql);
  538. ctrlConnection.setReturnValue(mockPreparedStatement);
  539. mockConnection.getMetaData();
  540. ctrlConnection.setReturnValue(mockDatabaseMetaData, 2);
  541. mockConnection.close();
  542. ctrlConnection.setVoidCallable(2);
  543. ctrlPreparedStatement.replay();
  544. ctrlDatabaseMetaData.replay();
  545. replay();
  546. BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter() {
  547. public void setValues(PreparedStatement ps, int i) throws SQLException {
  548. ps.setInt(1, ids[i]);
  549. }
  550. public int getBatchSize() {
  551. return ids.length;
  552. }
  553. };
  554. try {
  555. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  556. template.batchUpdate(sql, setter);
  557. fail("Should have failed because of SQLException in bulk update");
  558. }
  559. catch (DataAccessException ex) {
  560. assertTrue("Root cause is SQLException", ex.getCause() == sex);
  561. }
  562. ctrlPreparedStatement.verify();
  563. ctrlDatabaseMetaData.verify();
  564. }
  565. public void testCouldntGetConnectionInOperationOrLazilyInstantiatedExceptionTranslator() throws SQLException {
  566. SQLException sex = new SQLException("foo", "07xxx");
  567. // Change behaviour in setUp() because we only expect one call to getConnection():
  568. // none is necessary to get metadata for exception translator
  569. ctrlDataSource = MockControl.createControl(DataSource.class);
  570. mockDataSource = (DataSource) ctrlDataSource.getMock();
  571. mockDataSource.getConnection();
  572. // Expect two calls (one call after caching data product name): make get Metadata fail also
  573. ctrlDataSource.setThrowable(sex, 2);
  574. replay();
  575. try {
  576. JdbcTemplate template2 = new JdbcTemplate(mockDataSource);
  577. RowCountCallbackHandler rcch = new RowCountCallbackHandler();
  578. template2.query("SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch);
  579. fail("Shouldn't have executed query without a connection");
  580. catch (CannotGetJdbcConnectionException ex) {
  581. // pass
  582. assertTrue("Check root cause", ex.getCause() == sex);
  583. }
  584. ctrlDataSource.verify();
  585. }
  586. /**
  587.  * Verify that afterPropertiesSet invokes exception translator.
  588.  */
  589. public void testCouldntGetConnectionInOperationWithExceptionTranslatorInitialized() throws SQLException {
  590. SQLException sex = new SQLException("foo", "07xxx");
  591. ctrlDataSource = MockControl.createControl(DataSource.class);
  592. mockDataSource = (DataSource) ctrlDataSource.getMock();
  593. //mockConnection.getMetaData();
  594. //ctrlConnection.setReturnValue(null, 1);
  595. //mockConnection.close();
  596. //ctrlConnection.setVoidCallable(1);
  597. ctrlConnection.replay();
  598. // Change behaviour in setUp() because we only expect one call to getConnection():
  599. // none is necessary to get metadata for exception translator
  600. ctrlDataSource = MockControl.createControl(DataSource.class);
  601. mockDataSource = (DataSource) ctrlDataSource.getMock();
  602. // Upfront call for metadata - no longer the case
  603. //mockDataSource.getConnection();
  604. //ctrlDataSource.setReturnValue(mockConnection, 1);
  605. // One call for operation
  606. mockDataSource.getConnection();
  607. ctrlDataSource.setThrowable(sex, 2);
  608. ctrlDataSource.replay();
  609. try {
  610. JdbcTemplate template2 = new JdbcTemplate(mockDataSource);
  611. template2.afterPropertiesSet();
  612. RowCountCallbackHandler rcch = new RowCountCallbackHandler();
  613. template2.query("SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch);
  614. fail("Shouldn't have executed query without a connection");
  615. catch (CannotGetJdbcConnectionException ex) {
  616. // pass
  617. assertTrue("Check root cause", ex.getCause() == sex);
  618. }
  619. ctrlDataSource.verify();
  620. ctrlConnection.verify();
  621. }
  622. public void testCouldntGetConnectionInOperationWithExceptionTranslatorInitializedViaBeanProperty()
  623. throws Exception {
  624. doTestCouldntGetConnectionInOperationWithExceptionTranslatorInitialized(true);
  625. }
  626. public void testCouldntGetConnectionInOperationWithExceptionTranslatorInitializedInAfterPropertiesSet()
  627. throws Exception {
  628. doTestCouldntGetConnectionInOperationWithExceptionTranslatorInitialized(false);
  629. }
  630. /**
  631.  * If beanProperty is true, initialize via exception translator bean property;
  632.  * if false, use afterPropertiesSet().
  633.  */
  634. private void doTestCouldntGetConnectionInOperationWithExceptionTranslatorInitialized(boolean beanProperty)
  635. throws SQLException {
  636. SQLException sex = new SQLException("foo", "07xxx");
  637. ctrlConnection = MockControl.createControl(Connection.class);
  638. mockConnection = (Connection) ctrlConnection.getMock();
  639. //mockConnection.getMetaData();
  640. //ctrlConnection.setReturnValue(null, 1);
  641. //mockConnection.close();
  642. //ctrlConnection.setVoidCallable(1);
  643. ctrlConnection.replay();
  644. // Change behaviour in setUp() because we only expect one call to getConnection():
  645. // none is necessary to get metadata for exception translator
  646. ctrlDataSource = MockControl.createControl(DataSource.class);
  647. mockDataSource = (DataSource) ctrlDataSource.getMock();
  648. // Upfront call for metadata - no longer the case
  649. //mockDataSource.getConnection();
  650. //ctrlDataSource.setReturnValue(mockConnection, 1);
  651. // One call for operation
  652. mockDataSource.getConnection();
  653. ctrlDataSource.setThrowable(sex, 2);
  654. ctrlDataSource.replay();
  655. try {
  656. JdbcTemplate template2 = new JdbcTemplate();
  657. template2.setDataSource(mockDataSource);
  658. if (beanProperty) {
  659. // This will get a connection.
  660. template2.setExceptionTranslator(new SQLErrorCodeSQLExceptionTranslator(mockDataSource));
  661. }
  662. else {
  663. // This will cause creation of default SQL translator.
  664. // Note that only call should be effective.
  665. template2.afterPropertiesSet();
  666. template2.afterPropertiesSet();
  667. }
  668. RowCountCallbackHandler rcch = new RowCountCallbackHandler();
  669. template2.query(
  670. "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3",
  671. rcch);
  672. fail("Shouldn't have executed query without a connection");
  673. catch (CannotGetJdbcConnectionException ex) {
  674. // pass
  675. assertTrue("Check root cause", ex.getCause() == sex);
  676. }
  677. ctrlDataSource.verify();
  678. ctrlConnection.verify();
  679. }
  680. public void testPreparedStatementSetterSucceeds() throws Exception {
  681. final String sql = "UPDATE FOO SET NAME=? WHERE ID = 1";
  682. final String name = "Gary";
  683. int expectedRowsUpdated = 1;
  684. MockControl ctrlPreparedStatement =
  685. MockControl.createControl(PreparedStatement.class);
  686. PreparedStatement mockPreparedStatement =
  687. (PreparedStatement) ctrlPreparedStatement.getMock();
  688. mockPreparedStatement.setString(1, name);
  689. ctrlPreparedStatement.setVoidCallable();
  690. mockPreparedStatement.executeUpdate();
  691. ctrlPreparedStatement.setReturnValue(expectedRowsUpdated);
  692. mockPreparedStatement.getWarnings();
  693. ctrlPreparedStatement.setReturnValue(null);
  694. mockPreparedStatement.close();
  695. ctrlPreparedStatement.setVoidCallable();
  696. mockConnection.prepareStatement(sql);
  697. ctrlConnection.setReturnValue(mockPreparedStatement);
  698. ctrlPreparedStatement.replay();
  699. replay();
  700. PreparedStatementSetter pss = new PreparedStatementSetter() {
  701. public void setValues(PreparedStatement ps) throws SQLException {
  702. ps.setString(1, name);
  703. }
  704. };
  705. int actualRowsUpdated =
  706. new JdbcTemplate(mockDataSource).update(sql, pss);
  707. assertTrue(
  708. "updated correct # of rows",
  709. actualRowsUpdated == expectedRowsUpdated);
  710. ctrlPreparedStatement.verify();
  711. }
  712. public void testPreparedStatementSetterFails() throws Exception {
  713. final String sql = "UPDATE FOO SET NAME=? WHERE ID = 1";
  714. final String name = "Gary";
  715. SQLException sex = new SQLException();
  716. MockControl ctrlPreparedStatement =
  717. MockControl.createControl(PreparedStatement.class);
  718. PreparedStatement mockPreparedStatement =
  719. (PreparedStatement) ctrlPreparedStatement.getMock();
  720. mockPreparedStatement.setString(1, name);
  721. ctrlPreparedStatement.setVoidCallable();
  722. mockPreparedStatement.executeUpdate();
  723. ctrlPreparedStatement.setThrowable(sex);
  724. mockPreparedStatement.close();
  725. ctrlPreparedStatement.setVoidCallable();
  726. mockConnection.prepareStatement(sql);
  727. ctrlConnection.setReturnValue(mockPreparedStatement);
  728. ctrlPreparedStatement.replay();
  729. replay();
  730. PreparedStatementSetter pss = new PreparedStatementSetter() {
  731. public void setValues(PreparedStatement ps) throws SQLException {
  732. ps.setString(1, name);
  733. }
  734. };
  735. try {
  736. new JdbcTemplate(mockDataSource).update(sql, pss);
  737. fail("Should have failed with SQLException");
  738. }
  739. catch (DataAccessException ex) {
  740. assertTrue("root cause was preserved", ex.getCause() == sex);
  741. }
  742. ctrlPreparedStatement.verify();
  743. }
  744. public void testCouldntClose() throws Exception {
  745. MockControl ctrlStatement = MockControl.createControl(Statement.class);
  746. Statement mockStatement = (Statement) ctrlStatement.getMock();
  747. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  748. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  749. mockConnection.createStatement();
  750. ctrlConnection.setReturnValue(mockStatement);
  751. String sql = "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3";
  752. mockStatement.executeQuery(sql);
  753. ctrlStatement.setReturnValue(mockResultSet);
  754. mockResultSet.next();
  755. ctrlResultSet.setReturnValue(false);
  756. SQLException sex = new SQLException("bar");
  757. mockResultSet.close();
  758. ctrlResultSet.setThrowable(sex);
  759. mockStatement.getWarnings();
  760. ctrlStatement.setReturnValue(null);
  761. mockStatement.close();
  762. ctrlStatement.setThrowable(sex);
  763. mockConnection.close();
  764. ctrlConnection.setThrowable(sex);
  765. ctrlStatement.replay();
  766. ctrlResultSet.replay();
  767. replay();
  768. JdbcTemplate template2 = new JdbcTemplate(mockDataSource);
  769. RowCountCallbackHandler rcch = new RowCountCallbackHandler();
  770. template2.query("SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch);
  771. ctrlStatement.verify();
  772. ctrlResultSet.verify();
  773. }
  774. /**
  775.  * Mock objects allow us to produce warnings at will
  776.  */
  777. public void testFatalWarning() throws Exception {
  778. String sql = "SELECT forename from custmr";
  779. SQLWarning warnings = new SQLWarning("My warning");
  780. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  781. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  782. mockResultSet.next();
  783. ctrlResultSet.setReturnValue(false);
  784. mockResultSet.close();
  785. ctrlResultSet.setVoidCallable();
  786. MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
  787. PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
  788. mockStatement.executeQuery(sql);
  789. ctrlStatement.setReturnValue(mockResultSet);
  790. mockStatement.getWarnings();
  791. ctrlStatement.setReturnValue(warnings);
  792. mockStatement.close();
  793. ctrlStatement.setVoidCallable();
  794. mockConnection.createStatement();
  795. ctrlConnection.setReturnValue(mockStatement);
  796. ctrlResultSet.replay();
  797. ctrlStatement.replay();
  798. replay();
  799. JdbcTemplate t = new JdbcTemplate(mockDataSource);
  800. t.setIgnoreWarnings(false);
  801. try {
  802. t.query(sql, new RowCallbackHandler() {
  803. public void processRow(java.sql.ResultSet rs)
  804. throws java.sql.SQLException {
  805. rs.getByte(1);
  806. }
  807. });
  808. fail("Should have thrown exception on warning");
  809. }
  810. catch (SQLWarningException ex) {
  811. // Pass
  812. assertTrue(
  813. "Root cause of warning was correct",
  814. ex.getCause() == warnings);
  815. }
  816. ctrlResultSet.verify();
  817. ctrlStatement.verify();
  818. }
  819. public void testIgnoredWarning() throws Exception {
  820. String sql = "SELECT forename from custmr";
  821. SQLWarning warnings = new SQLWarning("My warning");
  822. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  823. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  824. mockResultSet.next();
  825. ctrlResultSet.setReturnValue(false);
  826. mockResultSet.close();
  827. ctrlResultSet.setVoidCallable();
  828. MockControl ctrlStatement =
  829. MockControl.createControl(PreparedStatement.class);
  830. PreparedStatement mockStatement =
  831. (PreparedStatement) ctrlStatement.getMock();
  832. mockStatement.executeQuery(sql);
  833. ctrlStatement.setReturnValue(mockResultSet);
  834. mockStatement.getWarnings();
  835. ctrlStatement.setReturnValue(warnings);
  836. mockStatement.close();
  837. ctrlStatement.setVoidCallable();
  838. mockConnection.createStatement();
  839. ctrlConnection.setReturnValue(mockStatement);
  840. ctrlResultSet.replay();
  841. ctrlStatement.replay();
  842. replay();
  843. // Too long: truncation
  844. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  845. template.setIgnoreWarnings(true);
  846. template.query(sql, new RowCallbackHandler() {
  847. public void processRow(java.sql.ResultSet rs)
  848. throws java.sql.SQLException {
  849. rs.getByte(1);
  850. }
  851. });
  852. ctrlResultSet.verify();
  853. ctrlStatement.verify();
  854. }
  855. /**
  856.  * Test that we see an SQLException translated using Error Code
  857.  */
  858. public void testSQLErrorCodeTranslation() throws Exception {
  859. final SQLException sex = new SQLException("I have a known problem", "99999", 1054);
  860. final String sql = "SELECT ID FROM CUSTOMER";
  861. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  862. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  863. mockResultSet.next();
  864. ctrlResultSet.setReturnValue(true);
  865. mockResultSet.close();
  866. ctrlResultSet.setVoidCallable();
  867. MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
  868. PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
  869. mockStatement.executeQuery(sql);
  870. ctrlStatement.setReturnValue(mockResultSet);
  871. mockStatement.close();
  872. ctrlStatement.setVoidCallable();
  873. MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class);
  874. DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock();
  875. mockDatabaseMetaData.getDatabaseProductName();
  876. ctrlDatabaseMetaData.setReturnValue("MySQL");
  877. mockDatabaseMetaData.getDriverVersion();
  878. ctrlDatabaseMetaData.setReturnValue("1.2.3");
  879. mockConnection.createStatement();
  880. ctrlConnection.setReturnValue(mockStatement);
  881. mockConnection.getMetaData();
  882. ctrlConnection.setReturnValue(mockDatabaseMetaData);
  883. ctrlResultSet.replay();
  884. ctrlStatement.replay();
  885. ctrlDatabaseMetaData.replay();
  886. replay();
  887. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  888. try {
  889. template.query(sql, new RowCallbackHandler() {
  890. public void processRow(java.sql.ResultSet rs) throws SQLException {
  891. throw sex;
  892. }
  893. });
  894. fail("Should have thrown exception");
  895. }
  896. catch (BadSqlGrammarException ex) {
  897. assertTrue("Wanted same exception back, not " + ex, sex == ex.getCause());
  898. }
  899. catch (Exception ex) {
  900. fail("Should have thrown BadSqlGrammarException exception, not " + ex);
  901. }
  902. ctrlResultSet.verify();
  903. ctrlStatement.verify();
  904. }
  905. /**
  906.  * Test that we see an SQLException translated using Error Code.
  907.  * If we provide the SQLExceptionTranslator, we shouldn't use a connection
  908.  * to get the metadata
  909.  */
  910. public void testUseCustomSQLErrorCodeTranslator() throws Exception {
  911. // Bad SQL state
  912. final SQLException sex = new SQLException("I have a known problem", "07000", 1054);
  913. final String sql = "SELECT ID FROM CUSTOMER";
  914. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  915. ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  916. mockResultSet.next();
  917. ctrlResultSet.setReturnValue(true);
  918. mockResultSet.close();
  919. ctrlResultSet.setVoidCallable();
  920. MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class);
  921. PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock();
  922. mockStatement.executeQuery(sql);
  923. ctrlStatement.setReturnValue(mockResultSet);
  924. mockStatement.close();
  925. ctrlStatement.setVoidCallable();
  926. mockConnection.createStatement();
  927. ctrlConnection.setReturnValue(mockStatement);
  928. // Change behaviour in setUp() because we only expect one call to getConnection():
  929. // none is necessary to get metadata for exception translator
  930. ctrlConnection = MockControl.createControl(Connection.class);
  931. mockConnection = (Connection) ctrlConnection.getMock();
  932. mockConnection.createStatement();
  933. ctrlConnection.setReturnValue(mockStatement, 1);
  934. mockConnection.close();
  935. ctrlConnection.setVoidCallable(1);
  936. ctrlConnection.replay();
  937. ctrlDataSource = MockControl.createControl(DataSource.class);
  938. mockDataSource = (DataSource) ctrlDataSource.getMock();
  939. mockDataSource.getConnection();
  940. ctrlDataSource.setReturnValue(mockConnection, 1);
  941. ctrlDataSource.replay();
  942. ///// end changed behaviour
  943. ctrlResultSet.replay();
  944. ctrlStatement.replay();
  945. JdbcTemplate template = new JdbcTemplate();
  946. template.setDataSource(mockDataSource);
  947. // Set custom exception translator
  948. template.setExceptionTranslator(new SQLStateSQLExceptionTranslator());
  949. template.afterPropertiesSet();
  950. try {
  951. template.query(sql, new RowCallbackHandler() {
  952. public void processRow(java.sql.ResultSet rs)
  953. throws SQLException {
  954. throw sex;
  955. }
  956. });
  957. fail("Should have thrown exception");
  958. }
  959. catch (BadSqlGrammarException ex) {
  960. assertTrue(
  961. "Wanted same exception back, not " + ex,
  962. sex == ex.getCause());
  963. ctrlResultSet.verify();
  964. ctrlStatement.verify();
  965. // We didn't call superclass replay() so we need to check these ourselves
  966. ctrlDataSource.verify();
  967. ctrlConnection.verify();
  968. }
  969. public void testNativeJdbcExtractorInvoked() throws Exception {
  970. MockControl ctrlResultSet = MockControl.createControl(ResultSet.class);
  971. final ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock();
  972. mockResultSet.close();
  973. ctrlResultSet.setVoidCallable(2);
  974. MockControl ctrlStatement = MockControl.createControl(Statement.class);
  975. final Statement mockStatement = (Statement) ctrlStatement.getMock();
  976. mockStatement.getWarnings();
  977. ctrlStatement.setReturnValue(null);
  978. mockStatement.close();
  979. ctrlStatement.setVoidCallable();
  980. MockControl ctrlStatement2 = MockControl.createControl(Statement.class);
  981. final Statement mockStatement2 = (Statement) ctrlStatement2.getMock();
  982. mockStatement2.executeQuery("my query");
  983. ctrlStatement2.setReturnValue(mockResultSet, 1);
  984. MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
  985. final PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
  986. mockPreparedStatement.getWarnings();
  987. ctrlPreparedStatement.setReturnValue(null);
  988. mockPreparedStatement.close();
  989. ctrlPreparedStatement.setVoidCallable();
  990. MockControl ctrlPreparedStatement2 = MockControl.createControl(PreparedStatement.class);
  991. final PreparedStatement mockPreparedStatement2 = (PreparedStatement) ctrlPreparedStatement2.getMock();
  992. mockPreparedStatement2.executeQuery();
  993. ctrlPreparedStatement2.setReturnValue(mockResultSet, 1);
  994. MockControl ctrlCallableStatement = MockControl.createControl(CallableStatement.class);
  995. final CallableStatement mockCallableStatement = (CallableStatement) ctrlCallableStatement.getMock();
  996. mockCallableStatement.getWarnings();
  997. ctrlCallableStatement.setReturnValue(null);
  998. mockCallableStatement.close();
  999. ctrlCallableStatement.setVoidCallable();
  1000. MockControl ctrlCallableStatement2 = MockControl.createControl(CallableStatement.class);
  1001. final CallableStatement mockCallableStatement2 = (CallableStatement) ctrlCallableStatement2.getMock();
  1002. mockCallableStatement2.execute();
  1003. ctrlCallableStatement2.setReturnValue(true);
  1004. mockCallableStatement2.getUpdateCount();
  1005. ctrlCallableStatement2.setReturnValue(-1);
  1006. mockCallableStatement2.getMoreResults();
  1007. ctrlCallableStatement2.setReturnValue(false);
  1008. mockCallableStatement2.getUpdateCount();
  1009. ctrlCallableStatement2.setReturnValue(-1);
  1010. ctrlResultSet.replay();
  1011. ctrlStatement.replay();
  1012. ctrlStatement2.replay();
  1013. ctrlPreparedStatement.replay();
  1014. ctrlPreparedStatement2.replay();
  1015. ctrlCallableStatement.replay();
  1016. ctrlCallableStatement2.replay();
  1017. mockConnection.createStatement();
  1018. ctrlConnection.setReturnValue(mockStatement, 1);
  1019. replay();
  1020. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  1021. template.setNativeJdbcExtractor(new NativeJdbcExtractor() {
  1022. public boolean isNativeConnectionNecessaryForNativeStatements() {
  1023. return false;
  1024. }
  1025. public boolean isNativeConnectionNecessaryForNativePreparedStatements() {
  1026. return false;
  1027. }
  1028. public boolean isNativeConnectionNecessaryForNativeCallableStatements() {
  1029. return false;
  1030. }
  1031. public Connection getNativeConnection(Connection con) {
  1032. return con;
  1033. }
  1034. public Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException {
  1035. return stmt.getConnection();
  1036. }
  1037. public Statement getNativeStatement(Statement stmt) {
  1038. assertTrue(stmt == mockStatement);
  1039. return mockStatement2;
  1040. }
  1041. public PreparedStatement getNativePreparedStatement(PreparedStatement ps) {
  1042. assertTrue(ps == mockPreparedStatement);
  1043. return mockPreparedStatement2;
  1044. }
  1045. public CallableStatement getNativeCallableStatement(CallableStatement cs) {
  1046. assertTrue(cs == mockCallableStatement);
  1047. return mockCallableStatement2;
  1048. }
  1049. public ResultSet getNativeResultSet(ResultSet rs) throws SQLException {
  1050. return rs;
  1051. }
  1052. });
  1053. template.query("my query", new ResultSetExtractor() {
  1054. public Object extractData(ResultSet rs2) throws SQLException {
  1055. assertEquals(mockResultSet, rs2);
  1056. return null;
  1057. }
  1058. });
  1059. template.query(new PreparedStatementCreator() {
  1060. public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
  1061. return mockPreparedStatement;
  1062. }
  1063. }, new ResultSetExtractor() {
  1064. public Object extractData(ResultSet rs2) throws SQLException {
  1065. assertEquals(mockResultSet, rs2);
  1066. return null;
  1067. }
  1068. });
  1069. template.call(new CallableStatementCreator() {
  1070. public CallableStatement createCallableStatement(Connection con) throws SQLException {
  1071. return mockCallableStatement;
  1072. }
  1073. },
  1074. new ArrayList());
  1075. ctrlStatement.verify();
  1076. ctrlStatement2.verify();
  1077. ctrlPreparedStatement.verify();
  1078. ctrlPreparedStatement2.verify();
  1079. ctrlCallableStatement.verify();
  1080. ctrlCallableStatement2.verify();
  1081. }
  1082. public void testStaticResultSetClosed() throws Exception {
  1083. MockControl ctrlResultSet;
  1084. ResultSet mockResultSet;
  1085. MockControl ctrlStatement;
  1086. Statement mockStatement;
  1087. MockControl ctrlResultSet2;
  1088. ResultSet mockResultSet2;
  1089. MockControl ctrlPreparedStatement;
  1090. PreparedStatement mockPreparedStatement;
  1091. try {
  1092. ctrlResultSet = MockControl.createControl(ResultSet.class);
  1093. mockResultSet = (ResultSet) ctrlResultSet.getMock();
  1094. mockResultSet.close();
  1095. ctrlResultSet.setVoidCallable();
  1096. ctrlStatement = MockControl.createControl(Statement.class);
  1097. mockStatement = (Statement) ctrlStatement.getMock();
  1098. mockStatement.executeQuery("my query");
  1099. ctrlStatement.setReturnValue(mockResultSet);
  1100. mockStatement.close();
  1101. ctrlStatement.setVoidCallable();
  1102. ctrlResultSet2 = MockControl.createControl(ResultSet.class);
  1103. mockResultSet2 = (ResultSet) ctrlResultSet2.getMock();
  1104. mockResultSet2.close();
  1105. ctrlResultSet2.setVoidCallable();
  1106. ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
  1107. mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
  1108. mockPreparedStatement.executeQuery();
  1109. ctrlPreparedStatement.setReturnValue(mockResultSet2);
  1110. mockPreparedStatement.close();
  1111. ctrlPreparedStatement.setVoidCallable();
  1112. mockConnection.createStatement();
  1113. ctrlConnection.setReturnValue(mockStatement);
  1114. mockConnection.prepareStatement("my query");
  1115. ctrlConnection.setReturnValue(mockPreparedStatement);
  1116. }
  1117. catch (SQLException sex) {
  1118. throw new RuntimeException("EasyMock initialization of jdbc objects failed");
  1119. }
  1120. ctrlResultSet.replay();
  1121. ctrlStatement.replay();
  1122. ctrlResultSet2.replay();
  1123. ctrlPreparedStatement.replay();
  1124. replay();
  1125. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  1126. try {
  1127. template.query("my query", new ResultSetExtractor() {
  1128. public Object extractData(ResultSet rs) throws SQLException {
  1129. throw new InvalidDataAccessApiUsageException("");
  1130. }
  1131. });
  1132. fail("Should have thrown InvalidDataAccessApiUsageException");
  1133. }
  1134. catch (InvalidDataAccessApiUsageException idaauex) {
  1135. // ok
  1136. }
  1137. try {
  1138. template.query(new PreparedStatementCreator() {
  1139. public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
  1140. return con.prepareStatement("my query");
  1141. }
  1142. public String getSql() {
  1143. return null;
  1144. }
  1145. }, new ResultSetExtractor() {
  1146. public Object extractData(ResultSet rs2) throws SQLException {
  1147. throw new InvalidDataAccessApiUsageException("");
  1148. }
  1149. });
  1150. fail("Should have thrown InvalidDataAccessApiUsageException");
  1151. }
  1152. catch (InvalidDataAccessApiUsageException idaauex) {
  1153. // ok
  1154. }
  1155. // verify confirms if test is successful by checking if close() called
  1156. ctrlResultSet.verify();
  1157. ctrlStatement.verify();
  1158. ctrlResultSet2.verify();
  1159. ctrlPreparedStatement.verify();
  1160. }
  1161. public void testExecuteClosed() throws Exception {
  1162. MockControl ctrlResultSet;
  1163. ResultSet mockResultSet;
  1164. MockControl ctrlCallable;
  1165. CallableStatement mockCallable;
  1166. try {
  1167. ctrlResultSet = MockControl.createControl(ResultSet.class);
  1168. mockResultSet = (ResultSet) ctrlResultSet.getMock();
  1169. mockResultSet.next();
  1170. ctrlResultSet.setReturnValue(true);
  1171. mockResultSet.close();
  1172. ctrlResultSet.setVoidCallable();
  1173. ctrlCallable = MockControl.createControl(CallableStatement.class);
  1174. mockCallable = (CallableStatement) ctrlCallable.getMock();
  1175. mockCallable.execute();
  1176. ctrlCallable.setReturnValue(true);
  1177. mockCallable.getUpdateCount();
  1178. ctrlCallable.setReturnValue(-1);
  1179. mockCallable.getResultSet();
  1180. ctrlCallable.setReturnValue(mockResultSet);
  1181. mockCallable.close();
  1182. ctrlCallable.setVoidCallable();
  1183. mockConnection.prepareCall("my query");
  1184. ctrlConnection.setReturnValue(mockCallable);
  1185. }
  1186. catch (SQLException sex) {
  1187. throw new RuntimeException("EasyMock initialization of jdbc objects failed");
  1188. }
  1189. ctrlResultSet.replay();
  1190. ctrlCallable.replay();
  1191. replay();
  1192. List params = new ArrayList();
  1193. params.add(new SqlReturnResultSet("", new RowCallbackHandler() {
  1194. public void processRow(ResultSet rs) throws SQLException {
  1195. throw new InvalidDataAccessApiUsageException("");
  1196. }
  1197. }));
  1198. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  1199. try {
  1200. template.call(new CallableStatementCreator() {
  1201. public CallableStatement createCallableStatement(Connection conn)
  1202. throws SQLException {
  1203. return conn.prepareCall("my query");
  1204. }
  1205. }, params);
  1206. }
  1207. catch (InvalidDataAccessApiUsageException idaauex) {
  1208. // ok
  1209. }
  1210. // verify confirms if test is successful by checking if close() called
  1211. ctrlResultSet.verify();
  1212. ctrlCallable.verify();
  1213. }
  1214. public void testQueryForList() throws Exception {
  1215. String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3";
  1216. MockControl ctrlResultSetMetaData;
  1217. ResultSetMetaData mockResultSetMetaData;
  1218. MockControl ctrlResultSet;
  1219. ResultSet mockResultSet;
  1220. MockControl ctrlStatement;
  1221. Statement mockStatement;
  1222. try {
  1223. ctrlResultSetMetaData = MockControl.createControl(ResultSetMetaData.class);
  1224. mockResultSetMetaData = (ResultSetMetaData) ctrlResultSetMetaData.getMock();
  1225. mockResultSetMetaData.getColumnCount();
  1226. ctrlResultSetMetaData.setReturnValue(1);
  1227. mockResultSetMetaData.getColumnName(1);
  1228. ctrlResultSetMetaData.setReturnValue("age", 2);
  1229. ctrlResultSet = MockControl.createControl(ResultSet.class);
  1230. mockResultSet = (ResultSet) ctrlResultSet.getMock();
  1231. mockResultSet.getMetaData();
  1232. ctrlResultSet.setReturnValue(mockResultSetMetaData);
  1233. mockResultSet.next();
  1234. ctrlResultSet.setReturnValue(true);
  1235. mockResultSet.getObject(1);
  1236. ctrlResultSet.setReturnValue(new Integer(11));
  1237. mockResultSet.next();
  1238. ctrlResultSet.setReturnValue(true);
  1239. mockResultSet.getObject(1);
  1240. ctrlResultSet.setReturnValue(new Integer(12));
  1241. mockResultSet.next();
  1242. ctrlResultSet.setReturnValue(false);
  1243. mockResultSet.close();
  1244. ctrlResultSet.setVoidCallable();
  1245. ctrlStatement = MockControl.createControl(Statement.class);
  1246. mockStatement = (Statement) ctrlStatement.getMock();
  1247. mockStatement.executeQuery(sql);
  1248. ctrlStatement.setReturnValue(mockResultSet);
  1249. mockStatement.getWarnings();
  1250. ctrlStatement.setReturnValue(null);
  1251. mockStatement.close();
  1252. ctrlStatement.setVoidCallable();
  1253. mockConnection.createStatement();
  1254. ctrlConnection.setReturnValue(mockStatement);
  1255. }
  1256. catch (SQLException sex) {
  1257. throw new RuntimeException("EasyMock initialization of jdbc objects failed");
  1258. }
  1259. ctrlResultSetMetaData.replay();
  1260. ctrlResultSet.replay();
  1261. ctrlStatement.replay();
  1262. replay();
  1263. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  1264. List li = template.queryForList(sql);
  1265. assertEquals("All rows returned", 2, li.size());
  1266. assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue());
  1267. assertEquals("Second row is Integer", 12, ((Integer)((Map)li.get(1)).get("age")).intValue());
  1268. ctrlResultSet.verify();
  1269. ctrlStatement.verify();
  1270. }
  1271. public void testQueryForListWithSingleRowAndColumn() throws Exception {
  1272. String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3";
  1273. MockControl ctrlResultSetMetaData;
  1274. ResultSetMetaData mockResultSetMetaData;
  1275. MockControl ctrlResultSet;
  1276. ResultSet mockResultSet;
  1277. MockControl ctrlStatement;
  1278. Statement mockStatement;
  1279. try {
  1280. ctrlResultSetMetaData = MockControl.createControl(ResultSetMetaData.class);
  1281. mockResultSetMetaData = (ResultSetMetaData) ctrlResultSetMetaData.getMock();
  1282. mockResultSetMetaData.getColumnCount();
  1283. ctrlResultSetMetaData.setReturnValue(1);
  1284. mockResultSetMetaData.getColumnName(1);
  1285. ctrlResultSetMetaData.setReturnValue("age", 2);
  1286. ctrlResultSet = MockControl.createControl(ResultSet.class);
  1287. mockResultSet = (ResultSet) ctrlResultSet.getMock();
  1288. mockResultSet.getMetaData();
  1289. ctrlResultSet.setReturnValue(mockResultSetMetaData);
  1290. mockResultSet.next();
  1291. ctrlResultSet.setReturnValue(true);
  1292. mockResultSet.getObject(1);
  1293. ctrlResultSet.setReturnValue(new Integer(11));
  1294. mockResultSet.next();
  1295. ctrlResultSet.setReturnValue(false);
  1296. mockResultSet.close();
  1297. ctrlResultSet.setVoidCallable();
  1298. ctrlStatement = MockControl.createControl(Statement.class);
  1299. mockStatement = (Statement) ctrlStatement.getMock();
  1300. mockStatement.executeQuery(sql);
  1301. ctrlStatement.setReturnValue(mockResultSet);
  1302. mockStatement.getWarnings();
  1303. ctrlStatement.setReturnValue(null);
  1304. mockStatement.close();
  1305. ctrlStatement.setVoidCallable();
  1306. mockConnection.createStatement();
  1307. ctrlConnection.setReturnValue(mockStatement);
  1308. }
  1309. catch (SQLException sex) {
  1310. throw new RuntimeException("EasyMock initialization of jdbc objects failed");
  1311. }
  1312. ctrlResultSetMetaData.replay();
  1313. ctrlResultSet.replay();
  1314. ctrlStatement.replay();
  1315. replay();
  1316. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  1317. List li = template.queryForList(sql);
  1318. assertEquals("All rows returned", 1, li.size());
  1319. assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue());
  1320. ctrlResultSet.verify();
  1321. ctrlStatement.verify();
  1322. }
  1323. public void testQueryForObject() throws Exception {
  1324. String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3";
  1325. MockControl ctrlResultSetMetaData;
  1326. ResultSetMetaData mockResultSetMetaData;
  1327. MockControl ctrlResultSet;
  1328. ResultSet mockResultSet;
  1329. MockControl ctrlStatement;
  1330. Statement mockStatement;
  1331. try {
  1332. ctrlResultSetMetaData = MockControl.createControl(ResultSetMetaData.class);
  1333. mockResultSetMetaData = (ResultSetMetaData) ctrlResultSetMetaData.getMock();
  1334. mockResultSetMetaData.getColumnCount();
  1335. ctrlResultSetMetaData.setReturnValue(1);
  1336. ctrlResultSet = MockControl.createControl(ResultSet.class);
  1337. mockResultSet = (ResultSet) ctrlResultSet.getMock();
  1338. mockResultSet.getMetaData();
  1339. ctrlResultSet.setReturnValue(mockResultSetMetaData);
  1340. mockResultSet.next();
  1341. ctrlResultSet.setReturnValue(true);
  1342. mockResultSet.getObject(1);
  1343. ctrlResultSet.setReturnValue(new Integer(22));
  1344. mockResultSet.next();
  1345. ctrlResultSet.setReturnValue(false);
  1346. mockResultSet.close();
  1347. ctrlResultSet.setVoidCallable();
  1348. ctrlStatement = MockControl.createControl(Statement.class);
  1349. mockStatement = (Statement) ctrlStatement.getMock();
  1350. mockStatement.executeQuery(sql);
  1351. ctrlStatement.setReturnValue(mockResultSet);
  1352. mockStatement.getWarnings();
  1353. ctrlStatement.setReturnValue(null);
  1354. mockStatement.close();
  1355. ctrlStatement.setVoidCallable();
  1356. mockConnection.createStatement();
  1357. ctrlConnection.setReturnValue(mockStatement);
  1358. }
  1359. catch (SQLException sex) {
  1360. throw new RuntimeException("EasyMock initialization of jdbc objects failed");
  1361. }
  1362. ctrlResultSetMetaData.replay();
  1363. ctrlResultSet.replay();
  1364. ctrlStatement.replay();
  1365. replay();
  1366. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  1367. Object o = template.queryForObject(sql, Integer.class);
  1368. assertEquals("Return of an object", "java.lang.Integer", o.getClass().getName());
  1369. ctrlResultSet.verify();
  1370. ctrlStatement.verify();
  1371. }
  1372. public void testQueryForInt() throws Exception {
  1373. String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3";
  1374. MockControl ctrlResultSetMetaData;
  1375. ResultSetMetaData mockResultSetMetaData;
  1376. MockControl ctrlResultSet;
  1377. ResultSet mockResultSet;
  1378. MockControl ctrlStatement;
  1379. Statement mockStatement;
  1380. try {
  1381. ctrlResultSetMetaData = MockControl.createControl(ResultSetMetaData.class);
  1382. mockResultSetMetaData = (ResultSetMetaData) ctrlResultSetMetaData.getMock();
  1383. mockResultSetMetaData.getColumnCount();
  1384. ctrlResultSetMetaData.setReturnValue(1);
  1385. ctrlResultSet = MockControl.createControl(ResultSet.class);
  1386. mockResultSet = (ResultSet) ctrlResultSet.getMock();
  1387. mockResultSet.getMetaData();
  1388. ctrlResultSet.setReturnValue(mockResultSetMetaData);
  1389. mockResultSet.next();
  1390. ctrlResultSet.setReturnValue(true);
  1391. mockResultSet.getObject(1);
  1392. ctrlResultSet.setReturnValue(new Integer(22));
  1393. mockResultSet.next();
  1394. ctrlResultSet.setReturnValue(false);
  1395. mockResultSet.close();
  1396. ctrlResultSet.setVoidCallable();
  1397. ctrlStatement = MockControl.createControl(Statement.class);
  1398. mockStatement = (Statement) ctrlStatement.getMock();
  1399. mockStatement.executeQuery(sql);
  1400. ctrlStatement.setReturnValue(mockResultSet);
  1401. mockStatement.getWarnings();
  1402. ctrlStatement.setReturnValue(null);
  1403. mockStatement.close();
  1404. ctrlStatement.setVoidCallable();
  1405. mockConnection.createStatement();
  1406. ctrlConnection.setReturnValue(mockStatement);
  1407. }
  1408. catch (SQLException sex) {
  1409. throw new RuntimeException("EasyMock initialization of jdbc objects failed");
  1410. }
  1411. ctrlResultSetMetaData.replay();
  1412. ctrlResultSet.replay();
  1413. ctrlStatement.replay();
  1414. replay();
  1415. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  1416. int i = template.queryForInt(sql);
  1417. assertEquals("Return of an int", 22, i);
  1418. ctrlResultSet.verify();
  1419. ctrlStatement.verify();
  1420. }
  1421. public void testQueryForLong() throws Exception {
  1422. String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3";
  1423. MockControl ctrlResultSetMetaData;
  1424. ResultSetMetaData mockResultSetMetaData;
  1425. MockControl ctrlResultSet;
  1426. ResultSet mockResultSet;
  1427. MockControl ctrlStatement;
  1428. Statement mockStatement;
  1429. try {
  1430. ctrlResultSetMetaData = MockControl.createControl(ResultSetMetaData.class);
  1431. mockResultSetMetaData = (ResultSetMetaData) ctrlResultSetMetaData.getMock();
  1432. mockResultSetMetaData.getColumnCount();
  1433. ctrlResultSetMetaData.setReturnValue(1);
  1434. ctrlResultSet = MockControl.createControl(ResultSet.class);
  1435. mockResultSet = (ResultSet) ctrlResultSet.getMock();
  1436. mockResultSet.getMetaData();
  1437. ctrlResultSet.setReturnValue(mockResultSetMetaData);
  1438. mockResultSet.next();
  1439. ctrlResultSet.setReturnValue(true);
  1440. mockResultSet.getObject(1);
  1441. ctrlResultSet.setReturnValue(new java.math.BigDecimal(87));
  1442. mockResultSet.next();
  1443. ctrlResultSet.setReturnValue(false);
  1444. mockResultSet.close();
  1445. ctrlResultSet.setVoidCallable();
  1446. ctrlStatement = MockControl.createControl(Statement.class);
  1447. mockStatement = (Statement) ctrlStatement.getMock();
  1448. mockStatement.executeQuery(sql);
  1449. ctrlStatement.setReturnValue(mockResultSet);
  1450. mockStatement.getWarnings();
  1451. ctrlStatement.setReturnValue(null);
  1452. mockStatement.close();
  1453. ctrlStatement.setVoidCallable();
  1454. mockConnection.createStatement();
  1455. ctrlConnection.setReturnValue(mockStatement);
  1456. }
  1457. catch (SQLException sex) {
  1458. throw new RuntimeException("EasyMock initialization of jdbc objects failed");
  1459. }
  1460. ctrlResultSetMetaData.replay();
  1461. ctrlResultSet.replay();
  1462. ctrlStatement.replay();
  1463. replay();
  1464. JdbcTemplate template = new JdbcTemplate(mockDataSource);
  1465. long l = template.queryForLong(sql);
  1466. assertEquals("Return of a long", 87, l);
  1467. ctrlResultSet.verify();
  1468. ctrlStatement.verify();
  1469. }
  1470. private static interface JdbcTemplateCallback {
  1471. void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch);
  1472. }
  1473. private static class Dispatcher implements PreparedStatementCreator, SqlProvider {
  1474. private int id;
  1475. private String sql;
  1476. public Dispatcher(int id, String sql) {
  1477. this.id = id;
  1478. this.sql = sql;
  1479. }
  1480. public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
  1481. PreparedStatement ps = conn.prepareStatement(sql);
  1482. ps.setInt(1, id);
  1483. return ps;
  1484. }
  1485. public String getSql() {
  1486. return sql;
  1487. }
  1488. }
  1489. }