Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
10.12.1.1, 10.13.1.1
-
None
-
None
-
Repro attached
-
Seen in production
Description
The following test:
- Creates a pooled connection
- Gets a connection from it, tries to performs an insert which fails not due to the database at all, but due to the broken InputStream passed in
- Tries to get a new connection object to do new operations on.
The second call to get a new connection fails, but we don't think it should as it makes it difficult to reuse pooled connections.
Additionally, the connectionErrorOccurred event is never called to inform us that the connection cannot be reused.
@Test public void testExceptionInsertingPoisonsPooledConnection() throws Exception { EmbeddedConnectionPoolDataSource dataSource = new EmbeddedConnectionPoolDataSource(); dataSource.setDatabaseName(temp.getRootPath().resolve("db").toString()); dataSource.setCreateDatabase("create"); PooledConnection pooledConnection = dataSource.getPooledConnection(); try { // Someone initialising the db try (Connection connection = pooledConnection.getConnection()) { try (Statement statement = connection.createStatement()) { statement.execute("CREATE TABLE blobs ( data BLOB(1G) )"); } } // Someone failing to insert something try (Connection connection = pooledConnection.getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO blobs (data) VALUES (?)")) { statement.setBinaryStream(1, new BrokenInputStream()); assertThat(statement::executeUpdate, throwsException(SQLException.class)); } // The next guy trying to do it right try (Connection connection = pooledConnection.getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO blobs (data) VALUES (?)")) { statement.setBinaryStream(1, new ByteArrayInputStream("data".getBytes(StandardCharsets.UTF_8))); assertThat(statement.executeUpdate(), is(1)); } } finally { pooledConnection.close(); } } private static class BrokenInputStream extends InputStream { @Override public int read() throws IOException { throw new NullPointerException("I forgot to check for null"); } }