Description
Using Java naming convention, all the Entity names and all the attributes of an entity must be written in camelCase.
But, in some cases, on the database side it would be more convenient to use "all lower case" or "snake case" names, expecially when you are using an already existent database. #5935
Database, Table and Column Naming Conventions?
How I Write SQL, Part 1: Naming Conventions
Now, to support this naming conventions, the only two option are the following:
1) breaking the Java entity/field naming convention
2) annotate all entities and attributes using the @Entity and @Column annotation
Using 2 is time expensive, prone to error, and sometimes breaks (partially) the readability of the entity.
Panache uses Hibernate 5, which provides two different naming strategies for use with Hibernate entities: an Implicit Naming Strategy (from DB to attribute) and a Physical Naming Strategy (from attribute to DB).
This tutorial shows an example of implementation.
It requires just a line of configuration in the application.properties
hibernate.physical_naming_strategy=<naming strategy class>
Implementation ideas
Allowing the use of custom class could bring many problems, to keep thing simple and save time maybe it would be enough to support just the 3 most common naming strategy:
I changed the title as it's not specific to Panache.
+1 to allow configuring a naming strategy, but in my experience people will need far more flexibility than having 3 basic choices.
As asked on the discussion forum, I would really like to see this in 1.2. Will remove a lot of boilerplate from my entities.
Nice.
Maybe this can be even improved by just defining a @ApplicationScoped? PhysicalNamingStrategy bean. In that case Quakrus could set it automatically and the user does not have to set the property explicitly. Of course if the user sets the property explicitly that one should be used always.
I think the problem with that is that it's all fun and games until 2 or
more PhysicalNamingStrategy beans exist in the app :)
Em Qua, 8 de jan de 2020 18:07, Marcel Overdijk notifications@github.com
escreveu:
Nice.
Maybe this can be even improved by just defining a @ApplicationScoped?
PhysicalNamingStrategy bean. In that case Quakrus could set it
automatically and the user does not have to set the property explicitly. Of
course if the user sets the property explicitly that one should be used
always.—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/quarkusio/quarkus/issues/6346?email_source=notifications&email_token=AAANG5PHOH5ZI2ALBTPK73DQ4Y57XA5CNFSM4J7Y245KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEIN7GSQ#issuecomment-572257098,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAANG5JBZANSMO66L2J72UTQ4Y57XANCNFSM4J7Y245A
.
Can someone provide an example if I want to use the org.hibernate.cfg.ImprovedNamingStrategy (which is the strategy which makes all properties and table names in snake_case format) ?
Should I only use this in application.properties to enable it?:
hibernate.physical_naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
Maybe it can be simplified by providing already built in common strategies:
hibernate.physical_naming_strategy="snake-case"
Yes, AFAIK that's what you need to do to use it
>
Just to clarify: This feature only allows defining a naming strategy, it does not provide naming strategies. org.hibernate.cfg.ImprovedNamingStrategy cannot be used as it does not implement PhysicalNamingStrategy; AFAIK snake strategy is not included with Hibernate.
The current implementation does not cover the whole issue as originally defined. "snake-case" causes java.lang.ClassNotFoundException
@zeljkot yes, you're right
Mostly, only snake_case and camelCase are used. Maybe the implementation of snake_case can be provided by quarkus, so it covers the most cases when using another naming strategy.
public final class SnakeCaseNamingStrategy implements PhysicalNamingStrategy {
@Override
public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return name;
}
@Override
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return name;
}
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
if (name == null) return null;
var tableName = name.getText();
if (!tableName.endsWith("s")) {
tableName = tableName.concat("s");
}
return Identifier.toIdentifier(tableName, name.isQuoted());
}
@Override
public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return toSnakeCase(name);
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return toSnakeCase(name);
}
private static Identifier toSnakeCase(Identifier name) {
if (name == null) return null;
String snakeCase = toSnakeCase(name.getText());
return Identifier.toIdentifier(snakeCase, name.isQuoted());
}
private static String toSnakeCase(String text) {
var buf = new StringBuilder(text);
for (int i = 1; i < buf.length() - 1; i++) {
if (Character.isLowerCase(buf.charAt(i - 1)) && Character.isUpperCase(buf.charAt(i))
&& Character.isLowerCase(buf.charAt(i + 1))) {
buf.insert(i++, '_');
}
}
return buf.toString().toLowerCase(Locale.ROOT);
}
}
Looks like you're interested in providing a PR? ;)
I'm not convinced there would be much value in having such a thing within the Quarkus repository?
Mind you, the point of this extension is to _boot_ Hibernate ORM - every further aspect belongs either in the Hibernate ORM repository or as a an extension to it.
In my personal experience, naming strategies are highly opinionated: people always want to customize _some_ detail.
That said, if you really believe that there's lots of people who'd be happy enough to just have a default snake_case and camelCase - maybe they belong in ORM so that there's more people benefitting from them?
@Sanne I also think that it is better to place such implementation within Hibernate ORM by default and not in quarkus. To provide this in Hibernate ORM makes sense, because mostly only snake_case or camelCase are used.