diff --git a/jOOQ-test/src/test/java/org/jooq/test/SQLServerTest.java b/jOOQ-test/src/test/java/org/jooq/test/SQLServerTest.java index e8d6adf75d..8c4ec95ec5 100644 --- a/jOOQ-test/src/test/java/org/jooq/test/SQLServerTest.java +++ b/jOOQ-test/src/test/java/org/jooq/test/SQLServerTest.java @@ -86,6 +86,7 @@ xxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxxxxxxxxxx +xxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxxxx @@ -1085,7 +1086,60 @@ xxxxxx xxxxx xxxxxxxxxxxxx xxxxxxx xxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + x + xxxxx + xxxxxx xxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x + xxxxxxxxx xxx xxxx x xxxxxx xxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + xxxxxxxxxx xxxxxx x xxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + xxxxxxxxxxxxxxxxxxxxxxxxx xx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxx xx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + xx xxxxxxx xxxxx xxxxxxx xx xxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxx + + xxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxx + + xxxxxxxxxxxxxxx xxxxxxxxxxxx + xxxxxxxxxxxxxxx xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxx xxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx + + xx xxxxxxx xxxxx xxxxxxx xx xxxxx + xxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xx x xxxxxxxxxxxxxxx + xx x xxxxxxxxxxxxxxx + xxxxxxxxxxxxxxx + xxxxxxxxxxxxxxx + + xxxxxxxxxxxxxxx xxxxxxxxxxxx + xxxxxxxxxxxxxxx xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + xx xxxxxxx xxxxx xxxxxxx xxxx xxxxx + xxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xx x xxxxxxxxxxxxxxx + xx x xxxxxxxxxxxxxxx + + xxxxxxxxxxxxxxx + xxxxxxxxxxxxxxx + xxxxx xxxxxx x xxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx + xxxxxxxxxxxxxxx xxxxxxxxxxx + xxxxxxxxxxxxxxx xxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x xxxxx diff --git a/jOOQ-test/src/test/java/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/test/java/org/jooq/test/jOOQAbstractTest.java index 35c70ab3b3..60f6c1f003 100644 --- a/jOOQ-test/src/test/java/org/jooq/test/jOOQAbstractTest.java +++ b/jOOQ-test/src/test/java/org/jooq/test/jOOQAbstractTest.java @@ -554,7 +554,7 @@ public abstract class jOOQAbstractTest< if (clean != null && clean.length > 0) { for (Table table : clean) { try { - create().delete(table); + create().delete(table).execute(); } catch (Exception e) { e.printStackTrace(); diff --git a/jOOQ/src/main/java/org/jooq/Transactional.java b/jOOQ/src/main/java/org/jooq/Transactional.java deleted file mode 100644 index 2671994db4..0000000000 --- a/jOOQ/src/main/java/org/jooq/Transactional.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright (c) 2009-2014, Data Geekery GmbH (http://www.datageekery.com) - * All rights reserved. - * - * This work is dual-licensed - * - under the Apache Software License 2.0 (the "ASL") - * - under the jOOQ License and Maintenance Agreement (the "jOOQ License") - * ============================================================================= - * You may choose which license applies to you: - * - * - If you're using this work with Open Source databases, you may choose - * either ASL or jOOQ License. - * - If you're using this work with at least one commercial database, you must - * choose jOOQ License - * - * For more information, please visit http://www.jooq.org/licenses - * - * Apache Software License 2.0: - * ----------------------------------------------------------------------------- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * jOOQ License and Maintenance Agreement: - * ----------------------------------------------------------------------------- - * Data Geekery grants the Customer the non-exclusive, timely limited and - * non-transferable license to install and use the Software under the terms of - * the jOOQ License and Maintenance Agreement. - * - * This library is distributed with a LIMITED WARRANTY. See the jOOQ License - * and Maintenance Agreement for more details: http://www.jooq.org/licensing - */ -package org.jooq; - -/** - * An FunctionalInterface that wraps transactional code. - * - * @author Lukas Eder - */ -public interface Transactional { - - /** - * Run the transactional code. - *

- * If this method completes normally, and this is not a nested transaction, - * then the transaction will be committed. If this method completes with an - * exception, then the transaction is rolled back to the beginning of this - * Transactional. - * - * @param configuration The Configuration in whose context the - * transaction is run. - * @return The outcome of the transaction. - * @throws Exception Any exception that will cause a rollback of the code - * contained in this transaction. If this is a nested - * transaction, the rollback may be performed only to the state - * before executing this Transactional. - */ - T run(Configuration configuration) throws Exception; -} diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java index 5775dfa739..a047d1e136 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java @@ -91,7 +91,7 @@ abstract class AbstractRecord extends AbstractStore implements Record { final Object[] values; final Object[] originals; final BitSet changed; - // final BitSet def; + boolean fetched; AbstractRecord(Collection> fields) { this(new RowImpl(fields)); @@ -108,7 +108,6 @@ abstract class AbstractRecord extends AbstractStore implements Record { this.values = new Object[size]; this.originals = new Object[size]; this.changed = new BitSet(size); - // this.def = new BitSet(size); } // ------------------------------------------------------------------------ @@ -299,9 +298,10 @@ abstract class AbstractRecord extends AbstractStore implements Record { private final void setValue(int index, Field field, T value) { // Relevant issues documenting this method's behaviour: - // [#945] - // [#948] - // [#979] + // [#945] Avoid bugs resulting from setting the same value twice + // [#948] To allow for controlling the number of hard-parses + // To allow for explicitly overriding default values + // [#979] Avoid modifying chnaged flag on unchanged primary key values UniqueKey key = getPrimaryKey(); @@ -347,6 +347,8 @@ abstract class AbstractRecord extends AbstractStore implements Record { } final void setValues(Field[] fields, AbstractRecord record) { + fetched = record.fetched; + for (Field field : fields) { int targetIndex = indexOrFail(fieldsRow(), field); int sourceIndex = indexOrFail(record.fieldsRow(), field); @@ -385,7 +387,7 @@ abstract class AbstractRecord extends AbstractStore implements Record { */ @Override public Record original() { - return Utils.newRecord((Class) getClass(), fields.fields.fields, configuration()) + return Utils.newRecord(fetched, (Class) getClass(), fields.fields.fields, configuration()) .operate(new RecordOperation() { @Override @@ -544,11 +546,11 @@ abstract class AbstractRecord extends AbstractStore implements Record { @Override public final R into(Table table) { - return Utils.newRecord(table, configuration()).operate(new TransferRecordState()); + return Utils.newRecord(fetched, table, configuration()).operate(new TransferRecordState()); } final R intoRecord(Class type) { - return Utils.newRecord(type, fields(), configuration()).operate(new TransferRecordState()); + return Utils.newRecord(fetched, type, fields(), configuration()).operate(new TransferRecordState()); } private class TransferRecordState implements RecordOperation { diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java index 6edaa36bc0..6fea3d8d21 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java @@ -566,7 +566,7 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro xxxx xxxxxxx x xx xxxxxxxx xx xxxxxxxxxxxxx x xxxxxxxxxxxx xxxxxx x xxxxx - xxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx x diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java index 98e51e6b61..47d4c54d6c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java @@ -444,7 +444,7 @@ abstract class AbstractStoreQuery extends AbstractQuery implem if (returning.size() == 1 && new Fields(returning).field(field) != null) { for (final Number id : ids) { getReturnedRecords().add( - Utils.newRecord(into, configuration) + Utils.newRecord(true, into, configuration) .operate(new RecordOperation() { @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java b/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java index 9d16ae4045..8ef6462819 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CursorImpl.java @@ -1408,7 +1408,7 @@ class CursorImpl implements Cursor { rs.updateRow(); } - record = Utils.newRecord((Class) type, fields, ctx.configuration()) + record = Utils.newRecord(true, (Class) type, fields, ctx.configuration()) .operate(initialiser); rows++; diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBindContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBindContext.java index 732a9e6843..137039ac7e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBindContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBindContext.java @@ -131,7 +131,7 @@ class DefaultBindContext extends AbstractBindContext { xx [/pro] */ // [#1126] Oracle's UDTs need to be bound with their type name if (UDTRecord.class.isAssignableFrom(type)) { - String typeName = Utils.newRecord((Class>) type) + String typeName = Utils.newRecord(false, (Class>) type) .operate(null) .getUDT() .getName(); diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java index f440669842..b37baec0e5 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java @@ -1673,7 +1673,7 @@ public class DefaultDSLContext implements DSLContext, Serializable { @Override public Record newRecord(Field... fields) { - return Utils.newRecord(RecordImpl.class, fields, configuration).operate(null); + return Utils.newRecord(false, RecordImpl.class, fields, configuration).operate(null); } // [jooq-tools] START [newRecord] @@ -1814,17 +1814,17 @@ public class DefaultDSLContext implements DSLContext, Serializable { @Override public > R newRecord(UDT type) { - return Utils.newRecord(type, configuration).operate(null); + return Utils.newRecord(false, type, configuration).operate(null); } @Override public R newRecord(Table table) { - return Utils.newRecord(table, configuration).operate(null); + return Utils.newRecord(false, table, configuration).operate(null); } @Override public R newRecord(Table table, final Object source) { - return Utils.newRecord(table, configuration) + return Utils.newRecord(false, table, configuration) .operate(new RecordOperation() { @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java b/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java index 937d796913..67c1d365cf 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java @@ -181,6 +181,7 @@ public class TableRecordImpl> extends AbstractRecord im } changed(false); + fetched = true; } return result; diff --git a/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java b/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java index f38129e69d..479f0df761 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/UpdatableRecordImpl.java @@ -141,19 +141,13 @@ public class UpdatableRecordImpl> extends TableReco TableField[] keys = getPrimaryKey().getFieldsArray(); boolean executeUpdate = false; - for (TableField field : keys) { - - // [#2764] If primary key values are allowed to be changed, - // inserting is only possible without prior loading of pk values - if (updatablePrimaryKeys(settings(this))) { - if (original(field) == null) { - executeUpdate = false; - break; - } - } - - // [#2764] Primary key value changes are interpreted as record copies - else { + // [#2764] If primary key values are allowed to be changed, + // inserting is only possible without prior loading of pk values + if (updatablePrimaryKeys(settings(this))) { + executeUpdate = fetched; + } + else { + for (TableField field : keys) { // If any primary key value is null or changed if (changed(field) || @@ -163,10 +157,10 @@ public class UpdatableRecordImpl> extends TableReco executeUpdate = false; break; } - } - // Otherwise, updates are possible - executeUpdate = true; + // Otherwise, updates are possible + executeUpdate = true; + } } int result = 0; @@ -316,7 +310,7 @@ public class UpdatableRecordImpl> extends TableReco @Override public final R copy() { - return Utils.newRecord(getTable(), configuration()) + return Utils.newRecord(fetched, getTable(), configuration()) .operate(new RecordOperation() { @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/Utils.java b/jOOQ/src/main/java/org/jooq/impl/Utils.java index 515af4ce37..be64846b2e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Utils.java +++ b/jOOQ/src/main/java/org/jooq/impl/Utils.java @@ -342,51 +342,51 @@ final class Utils { /** * Create a new record */ - static final RecordDelegate newRecord(Class type) { - return newRecord(type, null); + static final RecordDelegate newRecord(boolean fetched, Class type) { + return newRecord(fetched, type, null); } /** * Create a new record */ - static final RecordDelegate newRecord(Class type, Field[] fields) { - return newRecord(type, fields, null); + static final RecordDelegate newRecord(boolean fetched, Class type, Field[] fields) { + return newRecord(fetched, type, fields, null); } /** * Create a new record */ - static final RecordDelegate newRecord(Table type) { - return newRecord(type, null); + static final RecordDelegate newRecord(boolean fetched, Table type) { + return newRecord(fetched, type, null); } /** * Create a new record */ @SuppressWarnings("unchecked") - static final RecordDelegate newRecord(Table type, Configuration configuration) { - return (RecordDelegate) newRecord(type.getRecordType(), type.fields(), configuration); + static final RecordDelegate newRecord(boolean fetched, Table type, Configuration configuration) { + return (RecordDelegate) newRecord(fetched, type.getRecordType(), type.fields(), configuration); } /** * Create a new UDT record */ - static final > RecordDelegate newRecord(UDT type) { - return newRecord(type, null); + static final > RecordDelegate newRecord(boolean fetched, UDT type) { + return newRecord(fetched, type, null); } /** * Create a new UDT record */ - static final > RecordDelegate newRecord(UDT type, Configuration configuration) { - return newRecord(type.getRecordType(), type.fields(), configuration); + static final > RecordDelegate newRecord(boolean fetched, UDT type, Configuration configuration) { + return newRecord(fetched, type.getRecordType(), type.fields(), configuration); } /** * Create a new record */ @SuppressWarnings({ "unchecked", "rawtypes" }) - static final RecordDelegate newRecord(Class type, Field[] fields, Configuration configuration) { + static final RecordDelegate newRecord(boolean fetched, Class type, Field[] fields, Configuration configuration) { try { R record; @@ -402,6 +402,10 @@ final class Utils { record = Reflect.accessible(type.getDeclaredConstructor()).newInstance(); } + // [#3300] Records that were fetched from the database + if (record instanceof AbstractRecord) + ((AbstractRecord) record).fetched = fetched; + return new RecordDelegate(configuration, record); } catch (Exception e) { @@ -2989,7 +2993,7 @@ final class Utils { return null; } - return Utils.newRecord((Class>) type) + return Utils.newRecord(true, (Class>) type) .operate(new RecordOperation, SQLException>() { @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/Value.java b/jOOQ/src/main/java/org/jooq/impl/Value.java deleted file mode 100644 index b6dc73963e..0000000000 --- a/jOOQ/src/main/java/org/jooq/impl/Value.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * Copyright (c) 2009-2014, Data Geekery GmbH (http://www.datageekery.com) - * All rights reserved. - * - * This work is dual-licensed - * - under the Apache Software License 2.0 (the "ASL") - * - under the jOOQ License and Maintenance Agreement (the "jOOQ License") - * ============================================================================= - * You may choose which license applies to you: - * - * - If you're using this work with Open Source databases, you may choose - * either ASL or jOOQ License. - * - If you're using this work with at least one commercial database, you must - * choose jOOQ License - * - * For more information, please visit http://www.jooq.org/licenses - * - * Apache Software License 2.0: - * ----------------------------------------------------------------------------- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * jOOQ License and Maintenance Agreement: - * ----------------------------------------------------------------------------- - * Data Geekery grants the Customer the non-exclusive, timely limited and - * non-transferable license to install and use the Software under the terms of - * the jOOQ License and Maintenance Agreement. - * - * This library is distributed with a LIMITED WARRANTY. See the jOOQ License - * and Maintenance Agreement for more details: http://www.jooq.org/licensing - */ -package org.jooq.impl; - -import java.io.Serializable; - -/** - * @author Lukas Eder - */ -class Value0 implements Serializable { - - /** - * Generated UID - */ - private static final long serialVersionUID = -9065797545428164533L; - private T original; - private T value; - private boolean isChanged; - - Value0(T value) { - this(value, value, false); - } - - Value0(T value, T original, boolean isChanged) { - this.value = value; - this.original = original; - this.isChanged = isChanged; - } - - final T getValue() { - return value; - } - - final T getValue(T defaultValue) { - return value != null ? value : defaultValue; - } - - final T getOriginal() { - return original; - } - - @SuppressWarnings("unchecked") - final void intern() { - - // [#2177] Future versions of jOOQ may optimise this type check by - // performing type-decisions outside of Value - if (value instanceof String) { - value = (T) ((String) value).intern(); - } - } - - final void setValue(T val) { - - // The flag is always set to false: - // [#945] To avoid bugs resulting from setting the same value twice - // [#948] To allow for controlling the number of hard-parses - // To allow for explicitly overriding default values - setValue(val, false); - } - - final void setValue(T val, boolean primaryKey) { - - // [#948] Force setting of val in most cases, to allow for controlling - // the number of necessary hard-parses, and to allow for explicitly - // overriding default values with null - if (!primaryKey) { - isChanged = true; - } - - // [#979] Avoid modifying isChanged on unchanged primary key values - else { - - // [#945] Be sure that isChanged is never reset to false - if (value == null) { - isChanged = isChanged || (val != null); - } - else { - isChanged = isChanged || (!value.equals(val)); - } - } - - value = val; - } - - final boolean isChanged() { - return isChanged; - } - - final void setChanged(boolean isChanged) { - this.isChanged = isChanged; - - // [#1995] If a value is meant to be "unchanged", the "original" should - // match the supposedly "unchanged" value. - if (!isChanged) { - original = value; - } - } - - final void reset() { - isChanged = false; - value = original; - } - - // ------------------------------------------------------------------------ - // XXX: Object API - // ------------------------------------------------------------------------ -// -// @Override -// public boolean equals(Object obj) { -// if (this == obj) { -// return true; -// } -// -// if (obj instanceof Value0) { -// Value0 other = (Value0) obj; -// -// if (value == null) { -// return other.getValue() == null; -// } -// -// return value.equals(other.getValue()); -// } -// -// return false; -// } -// -// @Override -// public int hashCode() { -// if (value == null) { -// return 0; -// } -// -// return value.hashCode(); -// } - - @Override - public String toString() { - if (isChanged) { - return "*" + value; - } - else { - return "" + value; - } - } -}