[#3582] Record.from(Object) does not consider DataType.nullable() which may lead to constraint violations when inserting

This commit is contained in:
Lukas Eder 2014-08-22 14:54:25 +02:00
parent 278aa65195
commit a557297532
5 changed files with 49 additions and 11 deletions

View File

@ -66,6 +66,7 @@ import org.jooq.Record1;
import org.jooq.Record2;
import org.jooq.Record3;
import org.jooq.Record6;
import org.jooq.Result;
import org.jooq.SQLDialect;
import org.jooq.StoreQuery;
import org.jooq.Table;
@ -845,10 +846,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
}
public void testStoreVsExecuteInsert() throws Exception {
if (TIdentityPK() == null) {
log.info("SKIPPING", "store() vs. executeInsert() tests");
return;
}
Assume.assumeNotNull(TIdentityPK());
jOOQAbstractTest.reset = false;
@ -863,6 +861,29 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
assertEquals(1, i2.store());
}
public void testInsertWithRecordFrom() throws Exception {
Assume.assumeNotNull(TIdentityPK());
jOOQAbstractTest.reset = false;
IPK i1 = create().newRecord(TIdentityPK());
i1.setValue(TIdentityPK_ID(), null);
i1.setValue(TIdentityPK_VAL(), 1);
IPK i2 = create().newRecord(TIdentityPK(), i1);
assertEquals(1, i2.store());
IPK i3 = create().newRecord(TIdentityPK(), i1);
assertEquals(1, create().executeInsert(i3));
Result<IPK> list = create().fetch(TIdentityPK());
assertEquals(2, list.size());
assertNotNull(list.get(0).getValue(TIdentityPK_ID()));
assertNotNull(list.get(1).getValue(TIdentityPK_ID()));
assertEquals(1, (int) list.get(0).getValue(TIdentityPK_VAL()));
assertEquals(1, (int) list.get(1).getValue(TIdentityPK_VAL()));
}
public void testUpdatablesWithUpdatablePK() throws Exception {
DSLContext create = create();
create.configuration().settings().setUpdatablePrimaryKeys(true);

View File

@ -2172,6 +2172,11 @@ public abstract class jOOQAbstractTest<
new CRUDTests(this).testStoreVsExecuteInsert();
}
@Test
public void testInsertWithRecordFrom() throws Exception {
new CRUDTests(this).testInsertWithRecordFrom();
}
@Test
public void testFetchFromTXT() throws Exception {
new FormatTests(this).testFetchFromTXT();

View File

@ -49,6 +49,7 @@ import static org.jooq.impl.Utils.getMatchingGetter;
import static org.jooq.impl.Utils.getMatchingMembers;
import static org.jooq.impl.Utils.hasColumnAnnotations;
import static org.jooq.impl.Utils.indexOrFail;
import static org.jooq.impl.Utils.resetChangedOnNotNull;
import static org.jooq.impl.Utils.settings;
import java.lang.reflect.Method;
@ -827,6 +828,10 @@ abstract class AbstractRecord extends AbstractStore implements Record {
throw new MappingException("An error ocurred when mapping record from " + type, e);
}
}
// [#2700] [#3582] If a POJO attribute is NULL, but the column is NOT NULL
// then we should let the database apply DEFAULT values
resetChangedOnNotNull(this);
}
@Override

View File

@ -365,13 +365,7 @@ public abstract class DAOImpl<R extends UpdatableRecord<R>, P, T> implements DAO
for (Field<?> field : pk)
record.changed(field, false);
// [#2700] If a POJO attribute is NULL, but the column is NOT NULL
// then we should let the database apply DEFAULT values
for (int i = 0; i < record.size(); i++)
if (record.getValue(i) == null)
if (!record.field(i).getDataType().nullable())
record.changed(i, false);
Utils.resetChangedOnNotNull(record);
result.add(record);
}

View File

@ -457,6 +457,19 @@ final class Utils {
}
}
/**
* [#2700] [#3582] If a POJO attribute is NULL, but the column is NOT NULL
* then we should let the database apply DEFAULT values
*/
static void resetChangedOnNotNull(Record record) {
int size = record.size();
for (int i = 0; i < size; i++)
if (record.getValue(i) == null)
if (!record.field(i).getDataType().nullable())
record.changed(i, false);
}
/**
* Extract the configuration from an attachable.
*/