2

I'd like to make our JOOQ records more typesafe. For example, I'd like the BIGINT fields CUSTOMER.ID and ORDER.CUSTOMER_ID to be of type CustomerNo instead of just Long.

I can force JOOQ's code generator generate the correct fields using a combination of customType forcedType:

public final TableField<CustomerRecord, CustomerNo> ID = 
  createField("ID", SQLDataType.BIGINT.asConvertedDataType(new CustomerNoConverter()), this);

public final TableField<OrderRecord, CustomerNo> CUSTOMER_ID = 
  createField("CUSTOMER_ID", SQLDataType.BIGINT.asConvertedDataType(new CustomerNoConverter()), this);

However, that's not enough. For every single-field primary key of type Long, I need to create two classes, i.e. equivalents of CustomerNo and CustomerNoConverter. Of course, the most convenient way to do this is to use the JOOQ meta-model to loop over any such fields and generate the code for each of them.

Since the JOOQ model itself depends upon the to-be-generated classes, I will need to hook into JOOQ's code generator. However, I was unable to find a suitable callback mechanism for this task. How could I approach this problem?

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
blubb
  • 9,510
  • 3
  • 40
  • 82

1 Answers1

1

There is a pending feature request #2574 and some related ideas that aim at the code generator generating classes for each primary key / foreign key tuple, which would be rather useful for some additional type checking when expressing queries.

In the meantime, you can always extend jOOQ's JavaGenerator and add some additional classes to it. For instance, there's a "custom code section" section, where you can put your own code. Including your custom nested classes, for instance. The output could be something like:

public class Customer extends TableImpl<CustomerRecord> {
    public final TableField<CustomerRecord, CustomerNo> ID = 
      createField("ID", SQLDataType.BIGINT.asConvertedDataType(new CustomerNoConverter()), this);
    ...

    // Your additional genererated code here
    public static class CustomerNo {
        public final Long ID;
    }

    public static class CustomerNoConverter implements Converter<Long, CustomerNo> {
        ...
    }
}

Then, instead of using the XML config, use programmatic configuration to generate all the customTypes / forcedTypes.

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • 1
    Yes, that's the part I figured out already :) My question is regarding automating the creation of the "No" classes for >500 tables...
    – blubb Oct 16 '15 at 16:47
  • Well, it's a regular expression. You can match anything. Like `.*?\.CUSTOMER_ID`. If you provide more information about your schema, I can maybe provide more help :) – Lukas Eder Oct 16 '15 at 17:10
  • I misunderstood you, it appears. You obviously want 500 different types of type safe primary key types. You can always extend jOOQ's `JavaGenerator` and add some additional classes to it. For instance, there's a ["custom code section"](http://www.jooq.org/doc/latest/manual/code-generation/codegen-custom-code/) section, where you can put your own code. Including your custom nested classes, for instance. Then, instead of using the XML config, use [programmatic configuration](http://www.jooq.org/doc/latest/manual/code-generation/codegen-programmatic/) to generate all the customTypes / forcedTypes – Lukas Eder Oct 17 '15 at 15:32
  • Thanks, that's what I was aiming for. If you make this the answer I can approve it. :) – blubb Oct 19 '15 at 06:07
  • @blubb: Done. I'm very curious about this use-case. Would be very happy to learn more about it on the [user group](https://groups.google.com/d/forum/jooq-user). This would definitely be a very nice new built-in feature – Lukas Eder Oct 19 '15 at 06:29