[#1522] fetch().into(Table) doesn't initialise records correctly, such
that subsequent calls to store() will execute an INSERT, rather than an UPDATE
This commit is contained in:
parent
7dc81a977c
commit
1700d832b7
@ -139,9 +139,11 @@ public abstract class BaseTest<
|
||||
protected static final List<String> BOOK_TITLES = Arrays.asList("1984", "Animal Farm", "O Alquimista", "Brida");
|
||||
protected static final List<String> BOOK_FIRST_NAMES = Arrays.asList("George", "George", "Paulo", "Paulo");
|
||||
protected static final List<String> BOOK_LAST_NAMES = Arrays.asList("Orwell", "Orwell", "Coelho", "Coelho");
|
||||
protected static final List<Object> BOOK_NULLS = Arrays.asList(null, null, null, null);
|
||||
protected static final List<Integer> AUTHOR_IDS = Arrays.asList(1, 2);
|
||||
protected static final List<String> AUTHOR_FIRST_NAMES = Arrays.asList("George", "Paulo");
|
||||
protected static final List<String> AUTHOR_LAST_NAMES = Arrays.asList("Orwell", "Coelho");
|
||||
protected static final List<Object> AUTHOR_NULLS = Arrays.asList(null, null);
|
||||
|
||||
protected static final JooqLogger log = JooqLogger.getLogger(jOOQAbstractTest.class);
|
||||
|
||||
|
||||
@ -819,6 +819,69 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658,
|
||||
catch (MappingException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchIntoTable() throws Exception {
|
||||
jOOQAbstractTest.reset = false;
|
||||
|
||||
// JOIN two tables into a generated UpdatableRecord
|
||||
Result<B> result1 =
|
||||
create().select(
|
||||
TBook_ID(),
|
||||
TBook_TITLE(),
|
||||
TBook_AUTHOR_ID(),
|
||||
TAuthor_FIRST_NAME(),
|
||||
TAuthor_LAST_NAME())
|
||||
.from(TBook())
|
||||
.join(TAuthor())
|
||||
.on(TBook_AUTHOR_ID().equal(TAuthor_ID()))
|
||||
.orderBy(TBook_ID())
|
||||
.fetch()
|
||||
.into(TBook());
|
||||
|
||||
// Assure that only book-related fields are actually contained in Result
|
||||
assertEquals(4, result1.size());
|
||||
assertEquals(BOOK_IDS, result1.getValues(TBook_ID()));
|
||||
assertEquals(BOOK_TITLES, result1.getValues(TBook_TITLE()));
|
||||
assertEquals(BOOK_AUTHOR_IDS, result1.getValues(TBook_AUTHOR_ID()));
|
||||
assertEquals(BOOK_NULLS, result1.getValues(TBook_PUBLISHED_IN()));
|
||||
assertNull(result1.getField(TAuthor_FIRST_NAME()));
|
||||
assertNull(result1.getField(TAuthor_LAST_NAME()));
|
||||
|
||||
// Ensure that books can be updated using store()
|
||||
result1.get(0).setValue(TBook_TITLE(), "Changed");
|
||||
assertEquals(1, result1.get(0).store());
|
||||
|
||||
Result<B> books1 = create().selectFrom(TBook()).orderBy(TBook_ID()).fetch();
|
||||
assertEquals(4, books1.size());
|
||||
assertEquals(BOOK_IDS, books1.getValues(TBook_ID()));
|
||||
assertEquals(1, (int) books1.getValue(0, TBook_ID()));
|
||||
assertEquals(1, (int) books1.getValue(0, TBook_AUTHOR_ID()));
|
||||
assertEquals("Changed", books1.getValue(0, TBook_TITLE()));
|
||||
|
||||
// Without any fetched primary keys, the resulting records should be
|
||||
// inserted using store()
|
||||
B book =
|
||||
create().select(
|
||||
TBook_TITLE(),
|
||||
TBook_AUTHOR_ID(),
|
||||
TBook_PUBLISHED_IN(),
|
||||
TBook_LANGUAGE_ID())
|
||||
.from(TBook())
|
||||
.where(TBook_ID().equal(2))
|
||||
.fetchOne()
|
||||
.into(TBook());
|
||||
|
||||
assertNotNull(book);
|
||||
assertEquals("Animal Farm", book.getValue(TBook_TITLE()));
|
||||
assertNull(book.getValue(TBook_ID()));
|
||||
|
||||
book.setValue(TBook_ID(), 5);
|
||||
assertEquals(1, book.store());
|
||||
Result<B> books2 = create().selectFrom(TBook()).orderBy(TBook_ID()).fetch();
|
||||
assertEquals(5, books2.size());
|
||||
assertEquals("Animal Farm", books2.getValue(4, TBook_TITLE()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchIntoCustomTable() throws Exception {
|
||||
|
||||
|
||||
@ -1015,6 +1015,11 @@ public abstract class jOOQAbstractTest<
|
||||
new FetchTests(this).testReflectionWithImmutables();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchIntoTable() throws Exception {
|
||||
new FetchTests(this).testFetchIntoTable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchIntoCustomTable() throws Exception {
|
||||
new FetchTests(this).testFetchIntoCustomTable();
|
||||
|
||||
@ -212,6 +212,15 @@ abstract class AbstractRecord extends AbstractStore<Object> implements Record {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all value flags' changed status
|
||||
*/
|
||||
final void setAllChanged(boolean changed) {
|
||||
for (Value<?> value : getValues()) {
|
||||
value.setChanged(changed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + " [values=" + Arrays.asList(getValues()) + "]";
|
||||
@ -713,6 +722,25 @@ abstract class AbstractRecord extends AbstractStore<Object> implements Record {
|
||||
}
|
||||
}
|
||||
|
||||
// [#1522] If the primary key has been fully fetched, then changed
|
||||
// flags should all be reset in order for the returned record to be
|
||||
// updatable using store()
|
||||
if (result instanceof AbstractRecord) {
|
||||
UniqueKey<?> key = ((AbstractRecord) result).getMainKey();
|
||||
|
||||
if (key != null) {
|
||||
boolean isKeySet = true;
|
||||
|
||||
for (Field<?> field : key.getFields()) {
|
||||
isKeySet &= (getField(field) != null);
|
||||
}
|
||||
|
||||
if (isKeySet) {
|
||||
((AbstractRecord) result).setAllChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -203,8 +203,8 @@ class BatchStore implements Batch {
|
||||
|
||||
private void setAllUnchanged() {
|
||||
for (UpdatableRecord<?> record : records) {
|
||||
if (record instanceof TableRecordImpl) {
|
||||
((TableRecordImpl<?>) record).setAllChanged(false);
|
||||
if (record instanceof AbstractRecord) {
|
||||
((AbstractRecord) record).setAllChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,12 +110,6 @@ public class TableRecordImpl<R extends TableRecord<R>> extends TypeRecord<Table<
|
||||
return result;
|
||||
}
|
||||
|
||||
void setAllChanged(boolean changed) {
|
||||
for (Value<?> value : getValues()) {
|
||||
value.setChanged(changed);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final int storeInsert() {
|
||||
InsertQuery<R> insert = create().insertQuery(getTable());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user