JOOQ insertInto returning() 返回为Null

使用JOOQ插入数据,并返回插入Record为Null

类似以下插入操作

        UserRecord userRecord = dslContext.insertInto(USER)
                .set(USER.USERNAME, userinfoRequest.getUsername())
                .set(USER.CREATE_TIME, timestamp)
                .onDuplicateKeyIgnore()
                .returning()
                .fetchOne();

这里使用onDuplicateKeyIgnore,如果有主键或者唯一索引重复则不做插入操作

但是当操作成功之后,仍然没有Record返回。

Decode的原因是:

org.jooq.impl.AbstractDMLQuery

protected final int execute(ExecuteContext ctx, ExecuteListener listener) throws SQLException

            case MYSQL:
                listener.executeStart(ctx);
                result = ctx.statement().executeUpdate();
                ctx.rows(result);
                listener.executeEnd(ctx);
                rs = ctx.statement().getGeneratedKeys();

                int var6;
                try {
                    List<Object> list = new ArrayList();
                    if (rs != null) {
                        while(rs.next()) {
                            list.add(rs.getObject(1));
                        }
                    }

                    this.selectReturning(ctx.configuration(), list.toArray());
                    var6 = result;
                } finally {
                    JDBCUtils.safeClose(rs);
                }

                return var6;

如果执行插槽操作的表没有自增键,那么返回的ResultSet中没有值,执行

this.selectReturning(ctx.configuration(), list.toArray());

中的list为空。

    private final void selectReturning(Configuration configuration, Object... values) {
        if (values != null && values.length > 0 && this.table.getIdentity() != null) {
            final Field<Object> field = this.table.getIdentity().getField();
            Object[] ids = new Object[values.length];

            for(int i = 0; i < values.length; ++i) {
                ids[i] = field.getDataType().convert(values[i]);
            }

            if (this.returning.size() == 1 && (new Fields(this.returning)).field(field) != null) {
                //...
            } else {
                this.returned = this.create(configuration).select(this.returning).from(this.table).where(new Condition[]{field.in(ids)}).fetchInto(this.table);
            }
        }

    }

第一个if语句进不去,则this.returnedsize为0。

    public final Result<R> getReturnedRecords() {
        if (this.returned == null) {
            this.returned = new ResultImpl(this.configuration(), this.returning);
        }

        return this.returned;
    }
    public final R fetchOne() {
        ((InsertQuery)this.getDelegate()).execute();
        return Tools.filterOne(((InsertQuery)this.getDelegate()).getReturnedRecords());
    }

    static final <R extends Record> R filterOne(List<R> list) throws TooManyRowsException {
        int size = list.size();
        if (size == 1) {
            return (Record)list.get(0);
        } else if (size > 1) {
            throw new TooManyRowsException("Too many rows selected : " + size);
        } else {
            return null;
        }
    }

返回Null

备注:

An identity column is a column (also known as a field) in a database table that is made up of values generated by the database.

参考:https://en.wikipedia.org/wiki/Identity_column

一个回复在 “JOOQ insertInto returning() 返回为Null

  1. 您好,请教一下,我是使用 DSL.table(“mytable”) 做的插入操作,并没有使用jooq的代码生成,此时肯定是获取不到自增键的,那么如果想要获取还有其他方式吗, 我不希望使用jooq的代码生成

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部