Casting org.jooq.TableField<Long> to org.jooq.TableField<BigDecimal>

牧云@^-^@ 提交于 2020-01-17 06:40:18

问题


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:

  1. Fix your database schema and add some precision / scale to the column that generated a BigDecimal (in Oracle), or make it a BIGINT (in other databases)
  2. 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

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