Reputation: 341
Is there a way to configure JOOQ tool to convert smallint to Boolean using 'forcedTypes' tag for PostgresSQL database, without providing org.jooq.Converter implementation?
This is how the current configuration looks like:
<forcedTypes>
<forcedType>
<name>BOOLEAN</name>
<types>smallint.*</types>
</forcedType>
<forcedTypes>
JOOQ v3.9.1 is being used. PostgreSQL v9.6.6.
And unfortunately receives the next exception while storing information into the database:
Caused by: org.postgresql.util.PSQLException: ERROR: column "is_complete" is of type smallint but expression is of type boolean
Also tried with MySQL database and similar convertion from tinyint to Boolean works fine without any errors:
<forcedTypes>
<forcedType>
<name>BOOLEAN</name>
<types>tinyint.*</types>
</forcedType>
</forcedTypes>
Upvotes: 4
Views: 628
Reputation: 5930
You could do that, but I doubt that this is what you had in mind. You will have to create custom cast in PostgreSQL:
CREATE FUNCTION bool2int2(IN bool, OUT int2)
LANGUAGE SQL
AS $$
SELECT CASE WHEN $1 THEN 1::int2 WHEN $1 IS NOT NULL THEN 0::int2 END
$$;
DROP CAST IF EXISTS (bool AS int2);
CREATE CAST (bool AS int2)
WITH FUNCTION bool2int2(bool)
AS ASSIGNMENT;
Then this will work:
DROP TABLE IF EXISTS booltest;
CREATE TABLE booltest (id serial, boolval int2);
INSERT INTO booltest (boolval) VALUES(true),(false),(null::bool);
SELECT * FROM booltest;
id | boolval
----+---------
1 | 1
2 | 0
3 | (null);
Upvotes: 0
Reputation: 220762
No, this doesn't work as you're expecting (and it shouldn't). In jOOQ, the BOOLEAN
data type is bound to JDBC as the native BOOLEAN
type if the database supports it, e.g. PostgreSQL.
If the database doesn't support the type (e.g. MySQL / Oracle), then jOOQ will bind 0
/1
/NULL
number values. But you cannot enforce this behaviour for a dialect that would otherwise support BOOLEAN
types. But then again, why not just write that converter? It's really simple. Just add:
<forcedTypes>
<forcedType>
<userType>java.lang.Boolean</userType>
<converter>com.example.BooleanAsSmallintConverter</converter>
<!-- A bit risky. Are all smallints really booleans in your database? -->
<types>smallint.*</types>
</forcedType>
<forcedTypes>
And then:
class BooleanAsSmallintConverter extends AbstractConverter<Short, Boolean> {
public BooleanAsSmallintConverter() {
super(Short.class, Boolean.class);
}
@Override
public Boolean from(Short t) {
return t == null ? null : t.shortValue() != (short) 0;
}
@Override
public Short to(Boolean u) {
return u == null ? null : u ? Short.valueOf((short) 1) : Short.valueOf((short) 0);
}
}
Upvotes: 1