diff -r dd74a80a34d6 -r 1a95b1acb03f src/net/lemnik/eodsql/spi/util/DefaultDataObjectBinding.java --- a/src/net/lemnik/eodsql/spi/util/DefaultDataObjectBinding.java Fri Oct 29 21:13:08 2010 +0200 +++ b/src/net/lemnik/eodsql/spi/util/DefaultDataObjectBinding.java Wed Jan 05 11:58:48 2011 +0100 @@ -13,6 +13,7 @@ import java.util.Map; import java.util.Iterator; +import java.util.concurrent.atomic.AtomicReference; import net.lemnik.eodsql.QueryTool; import net.lemnik.eodsql.TypeMapper; @@ -38,7 +39,10 @@ private String[] keyColumns = null; - private volatile boolean complete = false; + private enum State { NOT_COMPLETE, SET_BINDING_TYPE_IN_PROCESS, COMPLETION_IN_PROCESS, COMPLETE } + + private AtomicReference complete + = new AtomicReference(State.NOT_COMPLETE); DefaultDataObjectBinding(final Class clazz) { setObjectType(clazz); @@ -46,8 +50,7 @@ private void complete( final ResultSetMetaData metaData) - throws SQLException, - EoDException { + throws EoDException { try { final DataObjectBindingCache cache = @@ -68,6 +71,31 @@ } } + private void ensureComplete(final ResultSetMetaData meta) + throws EoDException { + do { + final State state = complete.get(); + if (state == State.COMPLETE) { + break; + } + if (complete.compareAndSet(State.NOT_COMPLETE, State.COMPLETION_IN_PROCESS)) { + try { + complete(meta); + complete.set(State.COMPLETE); + break; + } catch (RuntimeException ex) { + complete.set(State.NOT_COMPLETE); + throw ex; + } + } else { + try { + Thread.sleep(1L); + } catch (InterruptedException ex) { + } + } + } while (true); + } + /** * The implementation of the {@link #getKeyColumns()} method. This * implementation has no direct effect on the {@link #keyColumns} @@ -197,8 +225,14 @@ @Override public boolean setBindingType(final BindingType bindingType) { - if(!complete) { - return super.setBindingType(bindingType); + if (complete.compareAndSet(State.NOT_COMPLETE, State.SET_BINDING_TYPE_IN_PROCESS)) { + try + { + return super.setBindingType(bindingType); + } finally + { + complete.set(State.NOT_COMPLETE); + } } return false; @@ -211,10 +245,7 @@ throws SQLException, EoDException { - if(!complete) { - complete(row.getMetaData()); - complete = true; - } + ensureComplete(row.getMetaData()); final int length = columns.length; @@ -241,10 +272,7 @@ final ResultSetMetaData meta = results.getMetaData(); - if(!complete) { - complete(meta); - complete = true; - } + ensureComplete(meta); final int length = columns.length;