Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code generation option to generate string constants for all object names #5210

Closed
slavap opened this issue Apr 20, 2016 · 18 comments
Closed

Comments

@slavap
Copy link

slavap commented Apr 20, 2016

Example:

public class PackageType extends TableImpl<PackageTypeRecord> {

    private static final long serialVersionUID = -2032229726;

    /**
     * The reference instance of <code>PACKAGE_TYPE</code>
     */
    public static final PackageType PACKAGE_TYPE = new PackageType();

    /**
     * The class holding records for this type
     */
    @Override
    public Class<PackageTypeRecord> getRecordType() {
        return PackageTypeRecord.class;
    }

    /**
     * The column <code>PACKAGE_TYPE.PACKAGE_TYPE_ID</code>.
     */
    public final TableField<PackageTypeRecord, Integer> PACKAGE_TYPE_ID = createField("PACKAGE_TYPE_ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");

    /**
     * The column <code>PACKAGE_TYPE.PACKAGE_TYPE</code>.
     */
    public final TableField<PackageTypeRecord, String> PACKAGE_TYPE_ = createField("PACKAGE_TYPE", org.jooq.impl.SQLDataType.VARCHAR.length(15).nullable(false), this, "");
...

It would be really nice to have:

public static final String FLD_NAME_PACKAGE_TYPE_ID = "PACKAGE_TYPE_ID";
public static final String FLD_NAME_PACKAGE_TYPE = "PACKAGE_TYPE";
...

then I can use these strings in annotations of my classes without repeating them. And code will be checked better by compiler.

@lukaseder
Copy link
Member

Thank you very much for your suggestion, @slavap.

You can already do this very easily by extending the JavaGenerator from jOOQ-codegen. There's a section in the manual that describes the "custom code sections" feature of the code generator:
http://www.jooq.org/doc/latest/manual/code-generation/codegen-custom-code

All you have to do is override JavaGenerator.generateTableClassFooter(TableDefinition, JavaWriter) and generate those methods into all of your tables.

While I don't want to exclude adding such a feature to jOOQ, I'd like to avoid having too many generated artefacts out of the box in the generated classes. The complexity of avoiding naming collisions grows quickly, so I'm putting this issue on the long term feature requests lists. Perhaps, if other use-cases arise that would profit from this, we'll be happy to review the idea.

@slavap
Copy link
Author

slavap commented Apr 22, 2016

Thank you for explanation!
But there should be no naming collisions, because these field names constants are declared in related table class, not in some other place.

@lukaseder
Copy link
Member

What if you have a prefix that collides with an existing column? E.g. FLD_ID is an existing column, and FLD_ID is the name of the ID column? :)

I'm of course exaggerating here. From experience, however, I'm pretty sure that this feature will cause a bit of maintenance work, while not adding a lot of value for most users, which is why I'd like to collect more use-cases, first.

@slavap
Copy link
Author

slavap commented Apr 22, 2016

Use cases are quite obvious. Anywhere you need to annotate something related to table or table fields (it could be some kind of meta information or for example hints for automatic UI construction), you have to repeat string values already presented in generated code. So there is a good chance to misspell or even getting runtime error when generated classes are changed together with db in the future. Compiler can check constants, but cannot check strings.

@lukaseder
Copy link
Member

I understand what you mean, but in 95% of all cases where you're not using annotations, you can get the names via TABLE.FIELD.getName(). So what I mean is I'm looking for more use-cases where the string really needs to be available as a constant. I currently don't see any, outside of annotations...

@slavap
Copy link
Author

slavap commented Apr 22, 2016

Sure, it's mostly for annotations, getName() works fine in other places.

@lukaseder
Copy link
Member

We'll think of this some more. I can certainly see the value of constants every now and then. But it's a tricky thing to add in a global context. I mean:

  • Are column names the only thing that users are interested in?
  • What about qualified column names?
  • Should qualified names extend catalog.schema.table.column, or schema.table.column only, or only table.column?
  • Is String the right type, or should we perhaps prefer org.jooq.Name?

etc.

@slavap
Copy link
Author

slavap commented Apr 22, 2016

  1. Column names and table names for sure.
  2. Qualified names are not so important IMO, and much harder to implement.
  3. Org.jooq.Name is definitely better than String

Thank you for considering this functionality, I understand it's not that simple, but may improve other parts of code base "outside" of jooq.

@lukaseder
Copy link
Member

lukaseder commented Apr 22, 2016

Regarding:

Org.jooq.Name is definitely better than String

Well... :) But you can't use those references in annotations...

@slavap
Copy link
Author

slavap commented Apr 22, 2016

It could be enum :-)

@lukaseder
Copy link
Member

Hah! Indeed. And a column enum could contain the column string, and reference the table enum, which references the schema enum, etc.

Very interesting thought, thanks!

@lukaseder
Copy link
Member

We'll put this on the long-term roadmap. I don't think the idea is ripe enough to be implemented. Sure, there's a short-term gain for usage of these values in annotations. But that seems like a use-case that very few people have, and if they do, they can easily extend the code generator to generate a new class like Names.java, which generates table names per schema (and perhaps a nested class Names per table to generate column names).

There are too many open questions (e.g. regarding qualification of such names), which might lead to either:

  • The feature being incomplete, and thus even less useful to most users
  • The feature being overengineered and complex to maintain

We'll keep this open to see if anyone else is interested in such a feature.

@lukaseder lukaseder self-assigned this Jan 15, 2020
@lukaseder lukaseder added this to To do in 3.13 Other improvements via automation Jan 15, 2020
@lukaseder
Copy link
Member

There has been some traction on this issue, but not enough.

  • It is quite easy to extend the code generator to achieve this in user code
  • The possible requirements with respect to generating case sensitivity information, identifier hierarchies, naming strategies mean that this is a significant task with possibly quite some maintenance overhead.

I'm closing this as "won't fix".

@lukaseder
Copy link
Member

Duplicate of this issue: #11375

I'm re-opening this, putting the issue on hold. The final decision on this feature hasn't been made. Prioritisation is definitely low for now.

@hemju
Copy link

hemju commented Apr 22, 2022

I was looking for the same functionality with the same use case. Since both issues #11375, #11920, and this issue are closed, may I assume correctly that this is out of the roadmap?

@lukaseder
Copy link
Member

It's currently not in a rejected state, but also not in any prioritised state, given that an out of the box feature will take quite some effort to tackle all the edge cases (naming conflicts, generator strategies, etc.) whereas it's already quite simple for users to implement themselves, by extending the JavaGenerator

@ambition-consulting
Copy link

I would also like to be able to use table names in annotations...

@lukaseder
Copy link
Member

lukaseder commented Aug 30, 2023

I'll implement this for jOOQ 3.19, given it gets traction time and again. There won't be much means of configuring the whereabouts of such constants, other than the usual generator strategies, keeping in mind that it's still quite simple to implement this manually by subclassing the JavaGenerator (which has also become easier in jOOQ 3.19, see #15213)

The assumptions will be:

  • This is an opt-in feature. It will be turned off by default, because most people won't need this, and it generates tons of extra classes that are unnecessary, unless needed. Configuration flag name: <globalObjectNames/>
    • While it may be tempting to include more fine-grained configuration on a per-object type basis, I won't implement this for now. Users can request this in the future, if needed.
  • To enable the main use case (usage of string literals in annotations), the strings must be static and known to the compiler, not dependent on any jOOQ API
  • The feature is implemented independently. Other jOOQ generated code will not reference these literals to prevent subtle issues with the static initialisation of generated code arising from circular dependencies in the schema. So, the strings will be declared redundantly. (I might change this in the future if there's a compelling use-case, but I think there won't be)
  • To avoid conflicts with other class members, the generated names will be generated in new "global object references" style classes. E.g.
    • Schema names will be generated in com.example.my_catalog.SchemaNames
    • Table names will be generated in com.example.my_catalog.my_schema.TableNames.
    • Column names in com.example.my_catalog.my_schema.tables.MyTableNames.
    • Benefits:
      • This approach also allows for generating only these files
      • File / class names as well as qualifying packages can be overridden in a generator strategy

Tasks

  • Add the configuration flag
  • Language support
    • Java
    • Kotlin
    • Scala
  • Documentation
  • Tests

3.19 Other improvements automation moved this from To do to Done Aug 30, 2023
lukaseder added a commit that referenced this issue Aug 31, 2023
Package UDTs generated wrong UDTNames objects, see [#10576]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

No branches or pull requests

4 participants