diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLListeners.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListeners.java index 6e22a2914..e21cf10a3 100644 --- a/querydsl-sql/src/main/java/com/querydsl/sql/SQLListeners.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListeners.java @@ -15,10 +15,11 @@ package com.querydsl.sql; import java.util.List; import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; -import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.querydsl.core.QueryMetadata; import com.querydsl.core.types.Expression; import com.querydsl.core.types.Path; @@ -38,7 +39,7 @@ public class SQLListeners implements SQLDetailedListener { @Nullable private final SQLDetailedListener parent; - private final List listeners = Lists.newArrayList(); + private final Set listeners = Sets.newLinkedHashSet(); public SQLListeners(SQLListener parent) { this.parent = new SQLListenerAdapter(parent); @@ -49,7 +50,15 @@ public class SQLListeners implements SQLDetailedListener { } public void add(SQLListener listener) { - listeners.add(new SQLListenerAdapter(listener)); + if (listener instanceof SQLListeners) { + for (SQLListener l : ((SQLListeners) listener).listeners) { + add(l); + } + } else if (listener instanceof SQLDetailedListener) { + listeners.add((SQLDetailedListener) listener); + } else { + listeners.add(new SQLListenerAdapter(listener)); + } } @Override diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertClause.java index 98ee502df..dd37840e1 100644 --- a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertClause.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertClause.java @@ -356,15 +356,16 @@ public class SQLInsertClause extends AbstractSQLClause implemen super.close(); } finally { stmt2.close(); + reset(); + endContext(context); } } }; } catch (SQLException e) { onException(context, e); - throw configuration.translate(queryString, constants, e); - } finally { reset(); endContext(context); + throw configuration.translate(queryString, constants, e); } } diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeClause.java index 2a26e3bec..dbbe1849c 100644 --- a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeClause.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeClause.java @@ -248,6 +248,8 @@ public class SQLMergeClause extends AbstractSQLClause implements super.close(); } finally { stmt2.close(); + reset(); + endContext(context); } } }; @@ -255,22 +257,25 @@ public class SQLMergeClause extends AbstractSQLClause implements if (hasRow()) { // update SQLUpdateClause update = new SQLUpdateClause(connection, configuration, entity); + update.addListener(listeners); populate(update); addKeyConditions(update); + reset(); + endContext(context); return EmptyResultSet.DEFAULT; } else { // insert SQLInsertClause insert = new SQLInsertClause(connection, configuration, entity); + insert.addListener(listeners); populate(insert); return insert.executeWithKeys(); } } } catch (SQLException e) { onException(context,e); - throw configuration.translate(queryString, constants, e); - } finally { reset(); endContext(context); + throw configuration.translate(queryString, constants, e); } } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/InsertBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/InsertBase.java index ebc35ea51..0a5bc89b9 100644 --- a/querydsl-sql/src/test/java/com/querydsl/sql/InsertBase.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/InsertBase.java @@ -22,6 +22,7 @@ import static org.junit.Assert.*; import java.sql.ResultSet; import java.sql.SQLException; import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; import org.joda.time.DateTime; import org.joda.time.LocalDate; @@ -239,6 +240,26 @@ public class InsertBase extends AbstractBaseTest { rs.close(); } + @Test + @ExcludeIn({CUBRID, SQLSERVER}) + public void insert_with_keys_listener() throws SQLException { + final AtomicBoolean result = new AtomicBoolean(); + SQLListener listener = new SQLBaseListener() { + @Override + public void end(SQLListenerContext context) { + result.set(true); + } + }; + SQLInsertClause clause = insert(survey).set(survey.name, "Hello World"); + clause.addListener(listener); + ResultSet rs = clause.executeWithKeys(); + assertFalse(result.get()); + assertTrue(rs.next()); + assertTrue(rs.getObject(1) != null); + rs.close(); + assertTrue(result.get()); + } + @Test @ExcludeIn({CUBRID, SQLSERVER}) public void insert_with_keys_Projected() throws SQLException { diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/MergeBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/MergeBase.java index cd3b06c5c..01ec6dd3b 100644 --- a/querydsl-sql/src/test/java/com/querydsl/sql/MergeBase.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/MergeBase.java @@ -20,6 +20,7 @@ import static org.junit.Assert.*; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.concurrent.atomic.AtomicBoolean; import org.junit.After; import org.junit.Before; @@ -61,6 +62,27 @@ public class MergeBase extends AbstractBaseTest { rs.close(); } + @Test + @ExcludeIn({H2, CUBRID, SQLSERVER}) + public void merge_with_keys_listener() throws SQLException { + final AtomicBoolean result = new AtomicBoolean(); + SQLListener listener = new SQLBaseListener() { + @Override + public void end(SQLListenerContext context) { + result.set(true); + } + }; + SQLMergeClause clause = merge(survey).keys(survey.id) + .set(survey.id, 7) + .set(survey.name, "Hello World"); + clause.addListener(listener); + ResultSet rs = clause.executeWithKeys(); + assertTrue(rs.next()); + assertTrue(rs.getObject(1) != null); + rs.close(); + assertTrue(result.get()); + } + @Test @IncludeIn(H2) public void merge_with_keys_and_subQuery() {