@After public void verifyClosed() throws Exception { if (verifyClosedAfter) { verify(callableStatement).close(); verify(connection, atLeastOnce()).close(); } }
@Test public void testPreparedStatementSetterFails() throws Exception { final String sql = "UPDATE FOO SET NAME=? WHERE ID = 1"; final String name = "Gary"; SQLException sqlException = new SQLException(); given(this.preparedStatement.executeUpdate()).willThrow(sqlException); PreparedStatementSetter pss = ps -> ps.setString(1, name); this.thrown.expect(DataAccessException.class); this.thrown.expect(exceptionCause(sameInstance(sqlException))); try { new JdbcTemplate(this.dataSource).update(sql, pss); } finally { verify(this.preparedStatement).setString(1, name); verify(this.preparedStatement).close(); verify(this.connection, atLeastOnce()).close(); } }
@Test public void testSqlUpdateEncountersSqlException() throws Exception { SQLException sqlException = new SQLException("bad update"); final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 4"; given(this.statement.executeUpdate(sql)).willThrow(sqlException); given(this.connection.createStatement()).willReturn(this.statement); this.thrown.expect(exceptionCause(sameInstance(sqlException))); try { this.template.update(sql); } finally { verify(this.statement).close(); verify(this.connection, atLeastOnce()).close(); } }
@Test public void testBogusUpdate() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int idParam = 6666; // It's because Integers aren't canonical SQLException sqlException = new SQLException("bad update"); given(this.preparedStatement.executeUpdate()).willThrow(sqlException); Dispatcher d = new Dispatcher(idParam, sql); this.thrown.expect(UncategorizedSQLException.class); this.thrown.expect(exceptionCause(equalTo(sqlException))); try { this.template.update(d); } finally { verify(this.preparedStatement).setInt(1, idParam); verify(this.preparedStatement).close(); verify(this.connection, atLeastOnce()).close(); } }
@Test public void testBatchUpdate() throws Exception { final String[] sql = {"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 1", "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 2"}; given(this.statement.executeBatch()).willReturn(new int[] {1, 1}); mockDatabaseMetaData(true); given(this.connection.createStatement()).willReturn(this.statement); JdbcTemplate template = new JdbcTemplate(this.dataSource, false); int[] actualRowsAffected = template.batchUpdate(sql); assertTrue("executed 2 updates", actualRowsAffected.length == 2); verify(this.statement).addBatch(sql[0]); verify(this.statement).addBatch(sql[1]); verify(this.statement).close(); verify(this.connection, atLeastOnce()).close(); }
@Test public void testBatchUpdateWithPlainMap() throws Exception { @SuppressWarnings("unchecked") final Map<String, Integer>[] ids = new Map[2]; ids[0] = Collections.singletonMap("id", 100); ids[1] = Collections.singletonMap("id", 200); final int[] rowsAffected = new int[] {1, 2}; given(preparedStatement.executeBatch()).willReturn(rowsAffected); given(connection.getMetaData()).willReturn(databaseMetaData); namedParameterTemplate = new NamedParameterJdbcTemplate(new JdbcTemplate(dataSource, false)); int[] actualRowsAffected = namedParameterTemplate.batchUpdate( "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id", ids); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); verify(connection).prepareStatement("UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"); verify(preparedStatement).setObject(1, 100); verify(preparedStatement).setObject(1, 200); verify(preparedStatement, times(2)).addBatch(); verify(preparedStatement, atLeastOnce()).close(); verify(connection, atLeastOnce()).close(); }
@Test public void testBatchUpdateWithListOfObjectArrays() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final List<Object[]> ids = new ArrayList<>(2); ids.add(new Object[] {100}); ids.add(new Object[] {200}); final int[] rowsAffected = new int[] {1, 2}; given(this.preparedStatement.executeBatch()).willReturn(rowsAffected); mockDatabaseMetaData(true); JdbcTemplate template = new JdbcTemplate(this.dataSource, false); int[] actualRowsAffected = template.batchUpdate(sql, ids); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); verify(this.preparedStatement, times(2)).addBatch(); verify(this.preparedStatement).setObject(1, 100); verify(this.preparedStatement).setObject(1, 200); verify(this.preparedStatement).close(); verify(this.connection, atLeastOnce()).close(); }
@Test public void testBatchUpdateWithListOfObjectArraysPlusTypeInfo() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final List<Object[]> ids = new ArrayList<>(2); ids.add(new Object[] {100}); ids.add(new Object[] {200}); final int[] sqlTypes = new int[] {Types.NUMERIC}; final int[] rowsAffected = new int[] {1, 2}; given(this.preparedStatement.executeBatch()).willReturn(rowsAffected); mockDatabaseMetaData(true); this.template = new JdbcTemplate(this.dataSource, false); int[] actualRowsAffected = this.template.batchUpdate(sql, ids, sqlTypes); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); verify(this.preparedStatement, times(2)).addBatch(); verify(this.preparedStatement).setObject(1, 100, sqlTypes[0]); verify(this.preparedStatement).setObject(1, 200, sqlTypes[0]); verify(this.preparedStatement).close(); verify(this.connection, atLeastOnce()).close(); }
@Test public void testAddInvoiceProcWithMetaDataUsingArrayParams() throws Exception { initializeAddInvoiceWithMetaData(false); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withProcedureName("add_invoice"); Number newId = adder.executeObject(Number.class, 1103, 3); assertEquals(4, newId.intValue()); verifyAddInvoiceWithMetaData(false); verify(connection, atLeastOnce()).close(); }
@Test public void testAddInvoiceFuncWithMetaDataUsingArrayParams() throws Exception { initializeAddInvoiceWithMetaData(true); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withFunctionName("add_invoice"); Number newId = adder.executeFunction(Number.class, 1103, 3); assertEquals(4, newId.intValue()); verifyAddInvoiceWithMetaData(true); verify(connection, atLeastOnce()).close(); }
@Test public void testBatchUpdateWithNoBatchSupport() throws Exception { final String[] sql = {"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 1", "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 2"}; given(this.statement.execute(sql[0])).willReturn(false); given(this.statement.getUpdateCount()).willReturn(1, 1); given(this.statement.execute(sql[1])).willReturn(false); mockDatabaseMetaData(false); given(this.connection.createStatement()).willReturn(this.statement); JdbcTemplate template = new JdbcTemplate(this.dataSource, false); int[] actualRowsAffected = template.batchUpdate(sql); assertTrue("executed 2 updates", actualRowsAffected.length == 2); verify(this.statement, never()).addBatch(anyString()); verify(this.statement).close(); verify(this.connection, atLeastOnce()).close(); }
@Test public void resolveTypeWithCustomVariableResolver() throws Exception { VariableResolver variableResolver = mock(VariableResolver.class); given(variableResolver.getSource()).willReturn(this); ResolvableType longType = ResolvableType.forClass(Long.class); given(variableResolver.resolveVariable(any())).willReturn(longType); ResolvableType variable = ResolvableType.forType( Fields.class.getField("typeVariableType").getGenericType(), variableResolver); ResolvableType parameterized = ResolvableType.forType( Fields.class.getField("parameterizedType").getGenericType(), variableResolver); assertThat(variable.resolve(), equalTo((Class) Long.class)); assertThat(parameterized.resolve(), equalTo((Class) List.class)); assertThat(parameterized.resolveGeneric(), equalTo((Class) Long.class)); verify(variableResolver, atLeastOnce()).resolveVariable(this.typeVariableCaptor.capture()); assertThat(this.typeVariableCaptor.getValue().getName(), equalTo("T")); }
@Test public void testBatchUpdateWithSqlParameterSourcePlusTypeInfo() throws Exception { SqlParameterSource[] ids = new SqlParameterSource[2]; ids[0] = new MapSqlParameterSource().addValue("id", 100, Types.NUMERIC); ids[1] = new MapSqlParameterSource().addValue("id", 200, Types.NUMERIC); final int[] rowsAffected = new int[] {1, 2}; given(preparedStatement.executeBatch()).willReturn(rowsAffected); given(connection.getMetaData()).willReturn(databaseMetaData); namedParameterTemplate = new NamedParameterJdbcTemplate(new JdbcTemplate(dataSource, false)); int[] actualRowsAffected = namedParameterTemplate.batchUpdate( "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id", ids); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); verify(connection).prepareStatement("UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"); verify(preparedStatement).setObject(1, 100, Types.NUMERIC); verify(preparedStatement).setObject(1, 200, Types.NUMERIC); verify(preparedStatement, times(2)).addBatch(); verify(preparedStatement, atLeastOnce()).close(); verify(connection, atLeastOnce()).close(); }
@Test public void testBatchUpdateWithNoBatchSupportAndSelect() throws Exception { final String[] sql = {"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 1", "SELECT * FROM NOSUCHTABLE"}; given(this.statement.execute(sql[0])).willReturn(false); given(this.statement.getUpdateCount()).willReturn(1); given(this.statement.execute(sql[1])).willReturn(true); mockDatabaseMetaData(false); given(this.connection.createStatement()).willReturn(this.statement); JdbcTemplate template = new JdbcTemplate(this.dataSource, false); this.thrown.expect(InvalidDataAccessApiUsageException.class); try { template.batchUpdate(sql); } finally { verify(this.statement, never()).addBatch(anyString()); verify(this.statement).close(); verify(this.connection, atLeastOnce()).close(); } }
@Test public void testAddInvoiceFuncWithMetaDataUsingMapParamSource() throws Exception { initializeAddInvoiceWithMetaData(true); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withFunctionName("add_invoice"); Number newId = adder.executeFunction(Number.class, new MapSqlParameterSource() .addValue("amount", 1103) .addValue("custid", 3)); assertEquals(4, newId.intValue()); verifyAddInvoiceWithMetaData(true); verify(connection, atLeastOnce()).close(); }
@Test public void testAddInvoiceProcWithMetaDataUsingMapParamSource() throws Exception { initializeAddInvoiceWithMetaData(false); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withProcedureName("add_invoice"); Number newId = adder.executeObject(Number.class, new MapSqlParameterSource() .addValue("amount", 1103) .addValue("custid", 3)); assertEquals(4, newId.intValue()); verifyAddInvoiceWithMetaData(false); verify(connection, atLeastOnce()).close(); }
@Test public void testAddInvoiceProcWithoutMetaDataUsingArrayParams() throws Exception { initializeAddInvoiceWithoutMetaData(false); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withProcedureName("add_invoice"); adder.declareParameters( new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER), new SqlOutParameter("newid", Types.INTEGER)); Number newId = adder.executeObject(Number.class, 1103, 3); assertEquals(4, newId.intValue()); verifyAddInvoiceWithoutMetaData(false); verify(connection, atLeastOnce()).close(); }
@Test public void testAddInvoiceFuncWithoutMetaDataUsingArrayParams() throws Exception { initializeAddInvoiceWithoutMetaData(true); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withFunctionName("add_invoice"); adder.declareParameters( new SqlOutParameter("return", Types.INTEGER), new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER)); Number newId = adder.executeFunction(Number.class, 1103, 3); assertEquals(4, newId.intValue()); verifyAddInvoiceWithoutMetaData(true); verify(connection, atLeastOnce()).close(); }
@Test public void testAddInvoiceProcWithoutMetaDataUsingMapParamSource() throws Exception { initializeAddInvoiceWithoutMetaData(false); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withProcedureName("add_invoice"); adder.declareParameters( new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER), new SqlOutParameter("newid", Types.INTEGER)); Number newId = adder.executeObject(Number.class, new MapSqlParameterSource(). addValue("amount", 1103). addValue("custid", 3)); assertEquals(4, newId.intValue()); verifyAddInvoiceWithoutMetaData(false); verify(connection, atLeastOnce()).close(); }
@Test public void testAddInvoiceFuncWithoutMetaDataUsingMapParamSource() throws Exception { initializeAddInvoiceWithoutMetaData(true); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withFunctionName("add_invoice"); adder.declareParameters( new SqlOutParameter("return", Types.INTEGER), new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER)); Number newId = adder.executeFunction(Number.class, new MapSqlParameterSource() .addValue("amount", 1103) .addValue("custid", 3)); assertEquals(4, newId.intValue()); verifyAddInvoiceWithoutMetaData(true); verify(connection, atLeastOnce()).close(); }