mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
ADD: Test and possible fix for (C)LOBs being handed out of connnection-context
Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>
This commit is contained in:
@@ -9,6 +9,7 @@ import io.ebeaninternal.server.query.DefaultSqlRow;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
public class DRawSqlService implements SpiRawSqlService {
|
||||
|
||||
@@ -49,6 +50,26 @@ public class DRawSqlService implements SpiRawSqlService {
|
||||
name = combine(meta.getSchemaName(i), meta.getTableName(i), name);
|
||||
}
|
||||
ret.put(name, resultSet.getObject(i));
|
||||
|
||||
// convert (C/B)LOBs to java objects.
|
||||
// A java.sql.Clob depends on an open connection, so storing this object in a map
|
||||
// that is accessed later, when the connection is closed, will result in a "connection is closed" exception.
|
||||
// From the java.sql.Clob documentation: "... which means that a Clob object contains a logical pointer to the SQL CLOB
|
||||
// data rather than the data itself."
|
||||
switch (meta.getColumnType(i)) {
|
||||
case Types.CLOB:
|
||||
case Types.NCLOB:
|
||||
ret.put(name, resultSet.getString(i));
|
||||
break;
|
||||
|
||||
case Types.BLOB:
|
||||
ret.put(name, resultSet.getBytes(i));
|
||||
break;
|
||||
|
||||
default:
|
||||
ret.put(name, resultSet.getObject(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -9,17 +9,26 @@ import io.ebean.RawSqlBuilder;
|
||||
import io.ebean.SqlRow;
|
||||
import io.ebean.annotation.ForPlatform;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
import io.ebeaninternal.server.core.DefaultServer;
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql.Sql;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.EBasicClob;
|
||||
import org.tests.model.basic.PersistentFileContent;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
import org.tests.model.rawsql.ERawSqlAggBean;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -283,4 +292,59 @@ public class TestRawSqlBuilder extends BaseTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCLobClosedConnection() throws Exception {
|
||||
final EBasicClob eBasicClob = new EBasicClob();
|
||||
eBasicClob.setName("eBasicClob");
|
||||
final String description = "This is the CLob description";
|
||||
eBasicClob.setDescription(description);
|
||||
DB.save(eBasicClob);
|
||||
|
||||
final String sql = "select description from ebasic_clob where id = ?";
|
||||
|
||||
List<SqlRow> rows = new ArrayList<>();
|
||||
final DataSourceConfig config = ((DefaultServer) DB.getDefault()).getServerConfig().getDataSourceConfig();
|
||||
|
||||
try (Connection connection = DriverManager.getConnection(config.getUrl(), config.getUsername(), config.getPassword());
|
||||
PreparedStatement stmt = connection.prepareStatement(sql)) {
|
||||
stmt.setLong(1, eBasicClob.getId());
|
||||
|
||||
try (ResultSet resultSet = stmt.executeQuery()) {
|
||||
while (resultSet.next()) {
|
||||
rows.add(RawSqlBuilder.sqlRow(resultSet, "true", false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(rows).hasSize(1);
|
||||
assertThat(rows.get(0).getString("description")).isEqualTo(description);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBLobClosedConnection() throws Exception {
|
||||
final PersistentFileContent pfc = new PersistentFileContent();
|
||||
final byte[] bytes = "This is the blob as String".getBytes(StandardCharsets.UTF_8);
|
||||
pfc.setContent(bytes);
|
||||
DB.save(pfc);
|
||||
|
||||
final String sql = "select content from persistent_file_content where id = ?";
|
||||
|
||||
List<SqlRow> rows = new ArrayList<>();
|
||||
final DataSourceConfig config = ((DefaultServer) DB.getDefault()).getServerConfig().getDataSourceConfig();
|
||||
|
||||
try (Connection connection = DriverManager.getConnection(config.getUrl(), config.getUsername(), config.getPassword());
|
||||
PreparedStatement stmt = connection.prepareStatement(sql)) {
|
||||
stmt.setLong(1, pfc.getId());
|
||||
|
||||
try (ResultSet resultSet = stmt.executeQuery()) {
|
||||
while (resultSet.next()) {
|
||||
rows.add(RawSqlBuilder.sqlRow(resultSet, "true", false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(rows).hasSize(1);
|
||||
assertThat(((Blob) rows.get(0).get("content")).getBytes(0, bytes.length)).isEqualTo(bytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user