问题
I was wondering if anybody can help me with casting the table object type from Long to BigDecimal?
In sql, the code is like this:
AND table_nameA.row_name = table_nameB.row_name
In jooq is just simple as:
and(table_nameA.row_name.eq( table_nameB.row_name))
I tried to cast it with
Select <? extends Record1<BigDecimal>
but I received a ClassCastException org.jooq.immpl.TableFieldImpl cannot be cast to org.jooq.Select
.
And when I tried to cast it with (BigDecimal)
, I received a ClassCastException org.jooq.immpl.TableFieldImpl cannot be cast to java.math.BigDecimal
.
thanks.
回答1:
There are several ways to work around this data type mismatch.
Data type coercion
If you don't care about the different data types generated by jOOQ for different NUMBER
/ DECIMAL
/ NUMERIC
precisions and scales, then you can use Field.coerce()
, which comes in three overloaded flavours:
- Field.coerce(Class) (coerce the type to a Java class)
- Field.coerce(DataType) (coerce the type to a
DataType
(including its data type binding)) - Field.coerce(Field) (coerce the type to the
DataType
of another field)
In your case, the latter probably works best:
table_nameA.row_name.eq(table_nameB.row_name.coerce(table_nameA.row_name))
Coercion does not affect the generated SQL, it just forces a Field
reference to be of a certain DataType
.
Raw type casting
The poor man's alternative to coercion might be a raw type cast:
table_nameA.row_name.eq((Field) table_nameB.row_name)
This is generally not recommended, but still maybe worth mentioning as a last resort.
SQL CAST()
You can always cast a Field
to a specific data type in SQL as well. This is useful if your data types have differing scales and you want the scales to match, e.g. because you want to treat 1.0001 = 1.0
or even '1' = 1
.
There are again three flavours of Field.cast()
:
- Field.cast(Class)
- Field.cast(DataType)
- Field.cast(Field)
In your case:
table_nameA.row_name.eq(table_nameB.row_name.cast(table_nameA.row_name))
This is different from coercing in that the generated SQL will contain a CAST()
(which might negatively impact performance, of course, as ordinary indexes cannot be used on the CAST
expression)
The generated SQL will look something like this:
TABLE_NAMEA.ROW_NAME = CAST(TABLE_NAMEB.ROW_NAME AS BIGINT)
Generate your code differently
If you believe that either of the generated types (e.g. Long
) was generated by mistake, you can either:
- Fix your database schema and add some precision / scale to the column that generated a
BigDecimal
(in Oracle), or make it aBIGINT
(in other databases) Re-generate your schema with the data type rewriting feature turned on for that column, e.g.
<forcedType> <name>BIGINT</name> <expression>(?i:.*?\.TABLE_NAMEB\.ROW_NAME)</expression> </forcedType>
来源:https://stackoverflow.com/questions/45834455/casting-org-jooq-tablefieldlong-to-org-jooq-tablefieldbigdecimal