Search code examples
javacode-generationjooq

JOOQ Metamodel: why is there no Table.rename(String)?


I am dynamically creating and using physical DB tables for which I only have one metamodel object. An example: I have one JOOQ class Customer in my metamodel, but I have CUSTOMER1, CUSTOMER2, etc. at runtime. I'd like to write strongly typed JOOQ queries for these dynamic tables. The following seems to do the trick:

Customer CUSTOMER1 = Customer.rename("CUSTOMER1")

Of course, there's a whole bunch of tables for which I need to do this. Unfortunately, I cannot leverage the rename method generically, because it is not part of the Table<R> interface. Is this an oversight or a deliberate measure against something I am missing?

Is there a robust and elegant way to achieve what I want, i.e. without resorting to reflection?

EDIT: the two tables are never used jointly in the same query. Concrete usage pattern is the following: At any given moment, a DB synonym CUSTOMER will point to one (the active), while the other is being modified (the shadow copy). Once the modification is complete, roles are swapped by pointing the synonym at the other one, and we start over. We do this to minimize "downtime" of heavy reporting result tables.


Solution

  • The answer to your question

    The question being in the title:

    why is there no Table.rename(String)?

    The feature was implemented in jOOQ 3.3 (#2921). The issue reads:

    As table renaming is not really a SQL DSL feature, the rename() method should be generated onto generated tables only, instead of being declared in org.jooq.Table

    In fact, this argument doesn't really make much sense. There are other "non-DSL" utilities on the DSL types. I don't see why rename() is special. The method should be declared on Table as you suggested. This might be done in the future (#13937).

    The answer to your problem

    From the update of your question, I understand that you don't really need that fine-grained renaming control. jOOQ's out of the box multi-tenancy feature will do. This is called "table mapping" in the manual:

    http://www.jooq.org/doc/latest/manual/sql-building/dsl-context/runtime-schema-mapping

    For the scope of a Configuration (most fine-grained scope: per-query level), you can rewrite any matching table name as such:

    Settings settings = new Settings()
        .withRenderMapping(new RenderMapping()
        .withSchemata(
            new MappedSchema().withInput("MY_SCHEMA")
                              .withOutput("MY_SCHEMA")
                              .withTables(
             new MappedTable().withInput("CUSTOMER")
                              .withOutput("CUSTOMER1"))));