Using UUID PK or FK in Firebird with Jooq

…衆ロ難τιáo~ 提交于 2019-12-24 00:03:59

问题


I have a table in Firebird with a PK column

CREATE TABLE TEST
(
  ID CHAR(16) CHARACTER SET OCTETS NOT NULL,
  CONSTRAINT PK_TEST PRIMARY KEY (ID)
);

OCTETS encoding are treated as bytes.

I create a converter

public class UUIDConverter implements Converter<byte[], UUID>{

    @Override
    public Class<byte[]> fromType() {
        return byte[].class;
    }

    @Override
    public Class<UUID> toType() {
        return UUID.class;
    }

    @Override
    public UUID from(byte[] bytes) {
        if (bytes == null) return null;
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        long high = bb.getLong();
        long low = bb.getLong();
        return new UUID(high, low);
    }

    @Override
    public byte[] to(UUID uuid) {
        if (uuid == null) return null;
        byte[] buffer = new byte[16];
        ByteBuffer bb = ByteBuffer.wrap(buffer);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        return buffer;
    }
}

Then I configured the converter in my pom (I'm using maven to generate the source)

<customTypes>
    <customType>
        <name>UUID</name>
        <converter>com.vas.database.UUIDConverter</converter>
    </customType>
</customTypes>
<forcedTypes>
    <forcedType>
        <name>VARBINARY</name>
        <expressions>ID|ID_.*</expressions>
    </forcedType>
</forcedTypes>

Although the code is generated, it is not what I expect.

public final TableField<TestRecord, byte[]> ID = createField("ID", org.jooq.impl.SQLDataType.VARBINARY.nullable(false), this, "");

This is what I would like it to be generated (I made the changes by hand and everything works wonderfully).

public final TableField<TestRecord, UUID> ID = createField("ID", org.jooq.impl.SQLDataType.VARBINARY.nullable(false), this, "", new UUIDConverter());

How do I make it work? (By the way, I'm using Firebird 3.0, Jooq 3.10.1 and Jaybird 2.2.13)


回答1:


There are several things to explain here:

1. Your config is wrong

In your current configuration, only this part applies to the code generator, rewriting your CHAR data type to VARBINARY using the data type rewriting feature:

<forcedTypes>
    <forcedType>
        <name>VARBINARY</name>
        <expressions>ID|ID_.*</expressions>
    </forcedType>
</forcedTypes>

The custom type for the UUID type is never applied because you don't force any column to the UUID type. (btw, you shouldn't name your custom type UUID, because that conflicts with SQLDataType.UUID)

2. You cannot rewrite a type twice

The current version of jOOQ 3.10 doesn't allow you to rewrite a type twice, i.e. from CHAR to VARBINARY and then from VARBINARY to your user-defined type. This is a limitation which might be fixed in a future version.

But right now, you have to implement this in one go.

By default, jOOQ would read / write CHAR types using java.lang.String and JDBC's corresponding PreparedStatement.setString() and ResultSet.getString() methods, regardless of any encoding / collation / etc. This is probably not what you want. Instead, you should not implement a Converter but a Binding as documented here: https://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindings

It allows you to "bind" your custom data type directly to JDBC, bypassing jOOQ's internal DefaultBinding semantics (which would call setString() and getString())



来源:https://stackoverflow.com/questions/47313967/using-uuid-pk-or-fk-in-firebird-with-jooq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!