Hi Samir, I'll comment inline
2017-05-09 4:57 GMT+02:00 Samir Faci <[email protected]>: > So I ran into this issue and was wondering if this was an implementation > over sight of it's intended. > > I have the following snippet of code: > > For reference, the record has a serial ID, that has little value though > for legacy reasons is the primary key of the record. > I'm curious: Why is this a "legacy"? Usually, the serial ID is the primary key. What would be a use-case not to do that? > ApiSettingParameterRecord record = > dslContext.newRecord(INTEGRATION.API_SETTING_PARAMETER); > record.setActive(true); > record.setDataSource(entity.getDataSource()); > record.setName(entity.getName()); > record.setType(entity.getType()); > record.setLength(entity.getLength()); > record.setUiOrder(entity.getUiOrder()); > record.setUiLabel(entity.getUiLabel()); > record.setIsPopulated(entity.getIsPopulated()); > record.setUrl(entity.getUrl()); > record.setAutoPopulated(entity.getAutoPopulated()); > record.setVisible(entity.getVisible()); > record.setVersion(entity.getVersion()); > > dslContext.insertInto(record.getTable()) > .set(record) > .onConflict(INTEGRATION.API_SETTING_PARAMETER.DATA_SOURCE, > INTEGRATION.API_SETTING_PARAMETER.VERSION, > INTEGRATION.API_SETTING_PARAMETER.ACTIVE, > INTEGRATION.API_SETTING_PARAMETER.UI_ORDER) > .doUpdate() > .set(record) > .execute(); > > > > After the code executes, I'd like to be able to do > > > record.refresh(); > > > > Which in this case doesn't work since the PKey is null. > Yes, that works as designed. The set(Record) clause you've used doesn't imply that the record will be modified by / tied to the specific INSERT statement, so the refresh() call wouldn't know what particular database record it should refresh itself to. > record.refresh() to get the ID of the record that was inserted, > > Instead, I'm forced to do a select using the onConflict conditional. > > ie. > > > record = > dslContext.select(record.fields()) > .from(INTEGRATION.API_SETTING_PARAMETER) > > .where(INTEGRATION.API_SETTING_PARAMETER.NAME.eq(entity.getName())) > > .and(INTEGRATION.API_SETTING_PARAMETER.DATA_SOURCE.eq(entity.getDataSource())) > > .and(INTEGRATION.API_SETTING_PARAMETER.VERSION.eq(entity.getVersion())) > > .and(INTEGRATION.API_SETTING_PARAMETER.ACTIVE.eq(Boolean.TRUE)) > > .orderBy(INTEGRATION.API_SETTING_PARAMETER.ACTIVE.desc()) > .fetchOneInto(ApiSettingParameterRecord.class); > > That's one option right now. > > > If this was a normal insert I could simply do a .returning(id); but that's > not supported with upserts, that's not feasible. > That will be supported in jOOQ 3.10, finally: https://github.com/jOOQ/jOOQ/issues/2123 But you can work around the issue in one of three ways: 1. Leverage the fact that the statement building DSL API is mutable, so you could assign the intermediate steps to a local variable and then call onConflict()... and returning() on that individually (this may break in jOOQ 4.0) 2. Leverage the fact that internally, the statement building DSL API is implemented by a single class InsertImpl, which implements all the DSL Step APIs, and thus offers all the required methods. This means you could cast the type returned by doUpdate().set(...) to InsertReturningStep and call returning() on that (this may break in jOOQ 4.0 as well) 3. Use the model API through DSLContext.insertQuery() Hope this helps, 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
