Using record.from(pojo) on a previously fetched record removes the ID field and prevents updates

26 views
Skip to first unread message

Daniel Einspanjer

unread,
Jan 10, 2017, 11:16:23 PM1/10/17
to jOOQ User Group
I did some reading on the current state of jOOQ and how to handle updating changed records. I thought I had a fair grasp on it, but I've hit a bit of a blocker, and I'd love some assistance.

What I'm seeing is if I do a Table.fetch of a record into an UpdatableRecord, and I then try to update that record with the data from a pojo for it using record.fetch(), the ID field "goes away".  It is no longer in the values and original arrays which means that reset() doesn't work on it, and I can't find a way to be able to update the record back into the DB.

Here is a sample of the code I was trying to get to work.  Please note the comments in the middle that indicate the specifics of the problem.

        DB1.ctx.fetch(DB1.T.SOURCETABLE).intoMap(DB1.T.SOURCETABLE.ID, SourcePojo.class))
final Collection<SourcePojo> sourcePojoRecords = (Collection<SourcePojo>) relationsMap.get(SourcePojo.class.getSimpleName()).values();
sourcePojoRecords
.forEach(sourcePojo -> {
Entity<SourcePojo> destinationPojo;
Table<? extends UpdatableRecord<?>> destinationTable;
Field<?> destinationId;
switch (sourcePojo.getSourcePojoType()) {
case 1:
destinationPojo = new DestinationsA();
destinationTable = DB2.T.DESTINATIONTABLE_A;
destinationId = DB2.T.DESTINATIONTABLE_A.ID;
break;
case 2:
destinationPojo = new DestinationsInfrastructure();
destinationTable = DB2.T.DESTINATIONTABLE_B;
destinationId = DB2.T.DESTINATIONTABLE_B.ID;
break;
case 3:
destinationPojo = new DestinationsInfrastructureMcus();
destinationTable = DB2.T.DESTINATIONTABLE_B_ALT;
destinationId = DB2.T.DESTINATIONTABLE_B_ALT.ID;
break;
default: // Other
destinationPojo = new Destinations();
destinationTable = DB2.T.DESTINATIONTABLE_OTHER;
destinationId = DB2.T.DESTINATIONTABLE_OTHER.ID;
break;
}
destinationPojo.migrateFrom(sourcePojo);

// At this point, destinationRecord has values[0] which is the ID, and it is valid.
UpdatableRecord<?> destinationRecord = DB2.ctx.fetchAny(destinationTable, DSL.condition("(destination_key->>'id')::int = ?", sourcePojo.getId()));

if (destinationRecord == null) {
destinationRecord = DB2.ctx.newRecord(destinationTable, destinationPojo);
} else {

// This call works fine even though it is basically a no-op since value[0] and original[0] match.
destinationRecord.reset(destinationId);

// After the call to from(), the destinationRecord no longer has value[0] or original[0].
// The changed bitset shows field[1] as the first change.
destinationRecord.from(destinationPojo);

// This throws an error that there is no such field in the database.
destinationRecord.reset(destinationId);


// The rest of this code seems to work fine. The other fields are compared and the changed flag is removed if they are identical.
UpdatableRecord<?> finalDestinationRecord = destinationRecord;
Arrays.stream(destinationRecord.fields()).forEach(field -> {
if (Objects.equals(finalDestinationRecord.original(field), finalDestinationRecord.get(field))) {
finalDestinationRecord.changed(field, false);
}
});
}

if (destinationRecord.changed()) {
// If I try to call store() without doing anything to the destinationId, it will insert it as a new record since it has no ID.
log.info("Updating Destination (ID: {} Key: {}) with changes.", destinationPojo.getId(), sourcePojo.getEntityKey().toJson());
destinationRecord.store();
} else {
log.info("Skipping update for unchanged Destination (ID: {} Key: {}) with changes.", destinationPojo.getId(), sourcePojo.getEntityKey().toJson());
}
});

Lukas Eder

unread,
Jan 16, 2017, 12:11:36 PM1/16/17
to jooq...@googlegroups.com
Hi Daniel,

Interesting, this shouldn't happen:
                        // This throws an error that there is no such field in the database.
destinationRecord.reset(destinationId);
What's the exact error this is throwing?

Lukas

--
You received this message because you are subscribed to the Google Groups "jOOQ User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Einspanjer

unread,
Jan 22, 2017, 11:46:47 PM1/22/17
to jOOQ User Group
Lukas,

I'm very sorry, but I don't have a reproducible case for this any longer.  I *believe* that the problem was resolved by ensuring I retrieved the primary key from the record and set it in the pojo before attempting to update the changed fields.  If I come across it again, I will be sure to extract some more useful information.

Lukas Eder

unread,
Jan 23, 2017, 1:54:06 AM1/23/17
to jooq...@googlegroups.com
Ok, thanks for the feedback!
Lukas

Reply all
Reply to author
Forward
0 new messages