Backwards incompatibility Many2Many field names affecting (existing) elasticsearch indexes
Overview of the issue
I'm currently in the process of updating a larger application (mostly JHipster generated) to 9.1.0 (from 8.11.0). During this, I noticed a backwards incompatibility, which I worked around by overriding the corresponding changes within my local blueprint. Especially, I'm having an issue with the changes made for #32373 in commit bba9b84eb6dd33d65de52ec6e2928144ea908328
Especially this line here that now force overwrites the plurals here: https://github.com/jhipster/generator-jhipster/blob/1aae62adbbe653a6d2d8eccef85adf132f82551d/generators/base-application/entity.ts#L218-L219
This makes the corresponding many2many relationship fields within the entity class have extra 'es' / 's' by using this logic https://github.com/jhipster/generator-jhipster/blob/1aae62adbbe653a6d2d8eccef85adf132f82551d/lib/utils/string-utils.ts#L39-L45
and effects then here in the class: https://github.com/jhipster/generator-jhipster/blob/1aae62adbbe653a6d2d8eccef85adf132f82551d/generators/java/generators/domain/templates/src/main/java/_package_/_entityPackage_/domain/_persistClass_.java.jhi.ejs#L176
As this class is also used for Elasticsearch indexing, a change in the naming of fields will invalidate existing elasticsearch indexes making data stored as part of those fields be not usable anymore, thus effectively requiring a reindexing: https://github.com/jhipster/generator-jhipster/blob/1aae62adbbe653a6d2d8eccef85adf132f82551d/generators/spring-boot/generators/data-elasticsearch/templates/src/main/java/_package_/_entityPackage_/repository/search/_entityClass_SearchRepository.java.ejs#L112
Motivation for or Use Case
I know, it was part of a major release with 9.0.0, but forcing existing users to perform a reindexing on a possibly multi-million rows relational database (which is my exact use case ;-)) is something that I would like to avoid, if somehow possible.
Also in my case the naming already contained plurals, which now makes the field names sound "funny": from a relationship named "jobs" it produces now "jobses". I also can't just rename the relationships as this again has effect on the column names on database side.
Reproduce the error
Related issues
Suggest a Fix
Just for everyone facing a similar issue, I leave this here, already on how to possibly work around this issue. I have this as part of a local blueprint (extending the spring-boot generator):
get [BaseApplicationGenerator.DEFAULT]() {
return this.asDefaultTaskGroup({
async overridePluralNames({ entities }) {
// 1. Fix entity-level plural properties.
// entityInstancePlural → setter parameter names (template: `<%- relationship.otherEntity.entityInstancePlural %>`)
// entityClassPlural → log messages and REST method names (template: `<%- entityClassPlural %>`)
// Both are cached as plain values; entityClassPlural = upperFirst(entityNamePlural).
for (const entity of entities) {
entity.entityInstancePlural = pluralize(entity.entityInstance);
entity.entityClassPlural = upperFirst(entity.entityInstancePlural);
}
// 2. Fix relationship-level plural properties cached on each relationship object.
for (const entity of entities) {
for (const relationship of entity.relationships) {
const plural = pluralize(relationship.relationshipFieldName);
relationship.relationshipFieldNamePlural = plural;
// For collection relationships (oneToMany / manyToMany) the propertyName and
// all capitalised / snake-cased derivatives must also be recomputed, because
// they were cached as plain values when the core generator ran and are used
// by templates for getter/setter names (propertyConsumerName /
// propertySupplierName are derived from propertyNameCapitalized).
if (relationship.collection) {
relationship.propertyName = plural;
// propertyNameCapitalized / propertyJavaBeanName both equal upperFirst(propertyName)
// for standard camelCase names; all three are independently cached.
relationship.propertyNameCapitalized = upperFirst(plural);
relationship.propertyNameUpperSnakeCase = snakeCase(plural).toUpperCase();
// propertyJavaBeanName → propertyConsumerName / propertySupplierName are computed
// in generators/java/application.js and cached as plain values.
relationship.propertyJavaBeanName = relationship.propertyNameCapitalized;
relationship.propertyConsumerName = `set${relationship.propertyNameCapitalized}`;
relationship.propertySupplierName = `get${relationship.propertyNameCapitalized}`;
// relationshipNameCapitalizedPlural is used for fetchBag method names in
// RepositoryWithBagRelationshipsImpl; computed in java/bootstrap from
// pluralize(relationshipNameCapitalized, { force: true }).
relationship.relationshipNameCapitalizedPlural = relationship.propertyNameCapitalized;
}
}
}
},
});
}
JHipster Version(s)
9.1.0 (worked differently in 8.11.0)
Browsers and Operating System
- Tickets opened without reproduction steps or that don't follow the template recommendation will be closed.
- This issue is prompt-related or an error that prevents JHipster from generating an application.
- I don't have a JDL otherwise I should open an JDL Issue
- The application is not successfully generated otherwise, I should open an Issue with jhipster info
- Checking this box is mandatory (this is just to show you read everything)
Source: jhipster/generator-jhipster