Closed Architha18 closed 1 week ago
A TableField
isn't a "member" as per the understanding of the GeneratorStrategy
. It's an "identifier." See:
https://www.jooq.org/doc/latest/manual/code-generation/codegen-object-naming/codegen-generatorstrategy/
/**
* Override this to specifiy what identifiers in Java should look like.
* This will just take the identifier as defined in the database.
*/
@Override
public String getJavaIdentifier(Definition definition) {
// The DefaultGeneratorStrategy disambiguates some synthetic object names,
// such as the MySQL PRIMARY key names, which do not really have a name
// Uncomment the below code if you want to reuse that logic.
// if (definition instanceof IndexDefinition)
// return super.getJavaIdentifier(definition);
return definition.getOutputName();
}
/**
* Override this method to define how Java members should be named. This is
* used for POJOs and method arguments
*/
@Override
public String getJavaMemberName(Definition definition, Mode mode) {
return definition.getOutputName();
}
I guess both the manual and the Javadoc could be a bit more clear.
I guess both the manual and the Javadoc could be a bit more clear.
Though, I think it's explained well enough:
Is there any chance of a condition within the jOOQ generator (possibly specific to XMLDatabase + bindings) where it decides not to call the configured strategy's getJavaIdentifier method for column definitions, perhaps falling back to some internal default that results in PascalCase (FieldName). @lukaseder
Is there any chance of a condition within the jOOQ generator (possibly specific to XMLDatabase + bindings) where it decides not to call the configured strategy's getJavaIdentifier method for column definitions, perhaps falling back to some internal default that results in PascalCase (FieldName). @lukaseder
I don't understnad why you'd want this. You can easily configure a generator strategy to do exactly that, why would that ever be a desirable default in "special cases?"
Hi @lukaseder (and team),
Thank you for the quick response and the clarification regarding getJavaIdentifier controlling the TableField variable name vs. getJavaMemberName for POJO members. That distinction is helpful.
Based on that clarification, I can confirm that my custom CodeGeneratorStrategy (code previously provided) does correctly override getJavaIdentifier. Inside this method, for column definitions, I have logic that removes the ENCRYPTED suffix and returns the result using StringUtils.toCamelCase(). For the panENCRYPTED column, this method is implemented to return the string "pan".
My POM configuration uses this strategy, XMLDatabase, the POSTGRES dialect, and applies an EncryptedStringBinding via
However, the key issue I'm encountering now is this:
To verify the strategy execution, I added System.out.println statements inside the getJavaIdentifier method (specifically within the if (definition instanceof ColumnDefinition) block) to log the exact value being returned.
When I run mvn clean generate-sources -X, the Maven output does not show these System.out.println messages executing for the panENCRYPTED column definition. Other parts of the strategy do seem active (e.g., getter/setter names in the Record class are generated correctly as getPan/setPan), but the specific call to getJavaIdentifier for the panENCRYPTED column definition appears to be skipped or bypassed entirely.
The generated code for the TableField variable in Anchor.java still reflects a name potentially derived from a default mechanism (Pan - PascalCase) rather than the value my strategy's getJavaIdentifier method is designed to return (pan - camelCase):
public final TableField<AnchorRecord, EncryptedString> Pan = createField(DSL.name("pan__ENCRYPTED"),
SQLDataType.CLOB.nullable(false), this, "", new EncryptedStringBinding());
So, to clarify my earlier question which might have been confusing: My testing indicates the generator isn't just producing unexpected casing, but it seems to be failing to call the configured getJavaIdentifier method for this specific column definition under these conditions (jOOQ 3.19.10, XMLDatabase,
Could this behaviour (the generator not invoking the strategy's getJavaIdentifier for a column definition when a binding is applied via XMLDatabase) be a potential bug or limitation?
I've already performed clean builds and checked the classpath, and the strategy class compiles fine. Let me know if providing the verbose -X logs or any other specific information would be helpful.
Thanks again for your time and help!
I'll be happy to help you further if you can provide a complete reproducer based on our template here: https://github.com/jOOQ/jOOQ-mcve. Using this template, it will be very simple to see what you're doing exactly, as the template helps create "minimal, complete, verifiable examples ("MCVE").
With a description or snippets pasted to github, it will be a lot more work (and often not even possible, because of accidental omissions, or errors when simplifying things) to analyse any problem.
Often, using the template also helps spot user errors, btw.
Expected behavior
When using a custom GeneratorStrategy that overrides getJavaMemberName to change the generated Java identifier for a database column (e.g., removing a suffix like __ENCRYPTED), the override is correctly applied when generating getter and setter methods in the TableRecord class (e.g., MyTableRecord.java).
However, the getJavaMemberName override appears to be ignored when generating the TableField variable declaration within the Table class itself (e.g., MyTable.java), but only when a <binding> or <converter> is also applied to the same column via <forcedType>. The TableField variable retains the name derived from the original database column name, ignoring the strategy's getJavaMemberName result for that specific declaration.
Actual behavior
The getJavaMemberName override in the custom GeneratorStrategy should consistently determine the Java identifier used for the TableField variable declaration in the Table class, even when a <binding> or <converter> is applied via <forcedType>. In the example provided, the field pan__ENCRYPTED should be generated as pan in the Anchor.java table class, consistent with the getPan/setPan methods in AnchorRecord.java.
Minimal Reproducible Example:
pom.xml Configuration:
src/main/resources/schema.xml:
com.capvel.platform.core.jooq.CodeGeneratorStrategy.java:
Dummy User Type (EncryptedString.java):
Dummy Binding (EncryptedStringBinding.java):
Steps to reproduce the problem
Set up a minimal Maven project with the files above. Run mvn clean generate-sources. Observe the generated files.
Actual Generated Code Snippets:
Anchor.java (Table class):
AnchorRecord.java (Record class):
The behavior seems tied to the presence of <binding> or <converter> in the <forcedType> for the same column.
jOOQ Version
JOOQ Version: 3.19.10
Database product and version
org.jooq.meta.xml.XMLDatabase
Java Version
openjdk version "17.0.14" 2025-01-21 LTS
JDBC / R2DBC driver name and version (include name if unofficial driver)
No response