在我的应用程序中,我正在使用flyway进行数据迁移,因此,我在UPPER_SNAKE_CASE
中定义了所有名称均具有所有名称的表(例如,用户-> USERS
,候选人组-> CANDIDATE_GROUP
)。我为不同的环境提供了2种配置:本地和docker。在本地环境中,我正在运行h2,在Docker中,我正在与MariaDB运行。
现在在h2上运行时一切正常,在MariaDB休眠状态下尝试对所有小写表执行操作,这将导致错误:
由以下原因引起:java.sql.SQLException:表'application.users'不存在
经过一些调查,我尝试将其添加到我的application-docker.yml
:
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
这会导致休眠状态下的表名大写:
Caused by: java.sql.SQLException: Table 'application.Users' doesn't exist
我知道我可以用注解@Table(name = "USERS")
命名所有表,并为所有列提供名称,但这不是我想要的解决方案。
不幸的是,我没有找到符合我的情况的策略(我知道this展示了如何创建自定义命名策略,但我认为我的情况并不罕见),我应该使用哪种命名策略MariaDB配置符合我的情况?
答案 0 :(得分:1)
Hibernate或Spring Data JPA中都没有UPPER_SNAKE_CASE
命名策略,但是可以通过扩展PhysicalNamingStrategyStandardImpl或SpringPhysicalNamingStrategy来定义自己的命名策略。
在Spring Data JPA中,这很容易,因为Spring已经将名称转换为snake_case:
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import java.io.Serializable;
import java.util.Locale;
public class UpperSnakeCaseSpringPhysicalNamingStrategyImpl extends SpringPhysicalNamingStrategy implements Serializable {
@Override
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
name = name.toUpperCase(Locale.ROOT);
return new Identifier(name, quoted);
}
}
要实现Hibernate转换为snake_case并至少覆盖5种方法中的2种:
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import java.io.Serializable;
import java.util.Locale;
public class UpperSnakeCasePhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl implements Serializable {
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
return new Identifier(addUnderscores(name.getText()), name.isQuoted());
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
return new Identifier(addUnderscores(name.getText()), name.isQuoted());
}
private static String addUnderscores(String name) {
final StringBuilder buf = new StringBuilder(name.replace('.', '_'));
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().toUpperCase(Locale.ROOT);
}
}
最后,应在application.properties或application.yml中设置自定义命名策略:
spring.jpa.hibernate.naming.physical-strategy=my.package.UpperSnakeCaseSpringPhysicalNamingStrategyImpl
有关SO的更多信息: