mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-08 08:39:19 +00:00
#1423 - Close resources - InputStream of entity bean properties of File type
This commit is contained in:
1 parent
c088cfa339
commit
50593a7f9d
7 files changed
+197
-26
No files matched your search
@@ -2,11 +2,16 @@ package io.ebeaninternal.server.persist;
|
||||
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.api.SpiProfileTransactionEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A batched statement that is held in BatchedPstmtHolder. It has a list of
|
||||
@@ -17,6 +22,8 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(BatchedPstmt.class);
|
||||
|
||||
/**
|
||||
* The underlying statement.
|
||||
*/
|
||||
@@ -40,6 +47,8 @@ public class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
|
||||
private int[] results;
|
||||
|
||||
private List<InputStream> inputStreams;
|
||||
|
||||
/**
|
||||
* Create with a given statement.
|
||||
*/
|
||||
@@ -117,16 +126,19 @@ public class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
}
|
||||
|
||||
private void executeAndCheckRowCounts() throws SQLException {
|
||||
try {
|
||||
results = pstmt.executeBatch();
|
||||
if (results.length != list.size()) {
|
||||
String s = "results array error " + results.length + " " + list.size();
|
||||
throw new SQLException(s);
|
||||
}
|
||||
|
||||
results = pstmt.executeBatch();
|
||||
if (results.length != list.size()) {
|
||||
String s = "results array error " + results.length + " " + list.size();
|
||||
throw new SQLException(s);
|
||||
}
|
||||
|
||||
// check for concurrency exceptions...
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
list.get(i).checkRowCount(results[i]);
|
||||
// check for concurrency exceptions...
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
list.get(i).checkRowCount(results[i]);
|
||||
}
|
||||
} finally {
|
||||
closeInputStreams();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,4 +160,23 @@ public class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
public int[] getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any inputStreams that should be closed after execution.
|
||||
*/
|
||||
public void registerInputStreams(List<InputStream> inputStreams) {
|
||||
this.inputStreams = inputStreams;
|
||||
}
|
||||
|
||||
private void closeInputStreams() {
|
||||
if (inputStreams != null) {
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.warn("Error closing inputStream ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,15 @@ public class BatchedPstmtHolder {
|
||||
* This will return null if no matching PreparedStatement is found.
|
||||
*/
|
||||
public PreparedStatement getStmt(String stmtKey, BatchPostExecute postExecute) {
|
||||
BatchedPstmt batchedPstmt = getBatchedPstmt(stmtKey, postExecute);
|
||||
return (batchedPstmt == null) ? null : batchedPstmt.getStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BatchedPstmt that holds the batched statement.
|
||||
*/
|
||||
public BatchedPstmt getBatchedPstmt(String stmtKey, BatchPostExecute postExecute) {
|
||||
|
||||
BatchedPstmt bs = stmtMap.get(stmtKey);
|
||||
if (bs == null) {
|
||||
// the PreparedStatement has need been created
|
||||
@@ -53,7 +62,7 @@ public class BatchedPstmtHolder {
|
||||
if (bsSize > maxSize) {
|
||||
maxSize = bsSize;
|
||||
}
|
||||
return bs.getStatement();
|
||||
return bs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,6 +46,8 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
*/
|
||||
protected DataBind dataBind;
|
||||
|
||||
protected BatchedPstmt batchedPstmt;
|
||||
|
||||
protected String sql;
|
||||
|
||||
/**
|
||||
@@ -273,20 +275,18 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
/**
|
||||
* Return a prepared statement taking into account batch requirements.
|
||||
*/
|
||||
protected PreparedStatement getPstmt(SpiTransaction t, String sql, PersistRequestBean<?> request,
|
||||
boolean genKeys) throws SQLException {
|
||||
protected PreparedStatement getPstmt(SpiTransaction t, String sql, PersistRequestBean<?> request, boolean genKeys) throws SQLException {
|
||||
|
||||
BatchedPstmtHolder batch = t.getBatchControl().getPstmtHolder();
|
||||
PreparedStatement stmt = batch.getStmt(sql, request);
|
||||
|
||||
if (stmt != null) {
|
||||
return stmt;
|
||||
batchedPstmt = batch.getBatchedPstmt(sql, request);
|
||||
if (batchedPstmt != null) {
|
||||
return batchedPstmt.getStatement();
|
||||
}
|
||||
|
||||
stmt = getPstmt(t, sql, genKeys);
|
||||
PreparedStatement stmt = getPstmt(t, sql, genKeys);
|
||||
|
||||
BatchedPstmt bs = new BatchedPstmt(stmt, genKeys, sql, t);
|
||||
batch.addStmt(bs, request);
|
||||
batchedPstmt = new BatchedPstmt(stmt, genKeys, sql, t);
|
||||
batch.addStmt(batchedPstmt, request);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,9 @@ public class InsertHandler extends DmlHandler {
|
||||
}
|
||||
dataBind = bind(pstmt);
|
||||
meta.bind(this, bean, withId, persistRequest.isPublish());
|
||||
|
||||
if (persistRequest.isBatched()) {
|
||||
batchedPstmt.registerInputStreams(dataBind.getInputStreams());
|
||||
}
|
||||
logSql(sql);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,9 @@ public class UpdateHandler extends DmlHandler {
|
||||
}
|
||||
dataBind = bind(pstmt);
|
||||
meta.bind(persistRequest, this, updatePlan);
|
||||
|
||||
if (persistRequest.isBatched()) {
|
||||
batchedPstmt.registerInputStreams(dataBind.getInputStreams());
|
||||
}
|
||||
setUpdateGenValues();
|
||||
|
||||
logSql(sql);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
|
||||
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
@@ -13,10 +16,14 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
public class DataBind {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DataBind.class);
|
||||
|
||||
private final DataTimeZone dataTimeZone;
|
||||
|
||||
private final PreparedStatement pstmt;
|
||||
@@ -25,6 +32,8 @@ public class DataBind {
|
||||
|
||||
private final StringBuilder bindLog = new StringBuilder();
|
||||
|
||||
private List<InputStream> inputStreams;
|
||||
|
||||
private int pos;
|
||||
|
||||
public DataBind(DataTimeZone dataTimeZone, PreparedStatement pstmt, Connection connection) {
|
||||
@@ -79,7 +88,24 @@ public class DataBind {
|
||||
}
|
||||
|
||||
public int executeUpdate() throws SQLException {
|
||||
return pstmt.executeUpdate();
|
||||
try {
|
||||
return pstmt.executeUpdate();
|
||||
} finally {
|
||||
closeInputStreams();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeInputStreams() {
|
||||
if (inputStreams != null) {
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.warn("Error closing InputStream that was bound to PreparedStatement", e);
|
||||
}
|
||||
}
|
||||
inputStreams = null;
|
||||
}
|
||||
}
|
||||
|
||||
public PreparedStatement getPstmt() {
|
||||
@@ -147,7 +173,19 @@ public class DataBind {
|
||||
pstmt.setString(++pos, String.valueOf(v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return any inputStreams that have been bound (and should be closed).
|
||||
* This is used for batched statement execution only.
|
||||
*/
|
||||
public List<InputStream> getInputStreams() {
|
||||
return inputStreams;
|
||||
}
|
||||
|
||||
public void setBinaryStream(InputStream inputStream, long length) throws SQLException {
|
||||
if (inputStreams == null) {
|
||||
inputStreams = new ArrayList<>();
|
||||
}
|
||||
inputStreams.add(inputStream);
|
||||
pstmt.setBinaryStream(++pos, inputStream, length);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user