我正在将应用程序从 Hibernate 4 迁移到 Hibernate 5。 我无法通过命名策略取胜。当然我已经读过: hibernate ImprovedNamingStrategy 会覆盖实体中的表名称 并且 ImprovedNamingStrategy 在 Hibernate 5 中不再工作
我已经将
AnnotationConfiguration
更改为 Configuration
,现在我有:
private void reloadHibernateSessionFactoryFromConf(Map<String, String> prop) {
try {
sessionFactory = null;
Configuration config = new Configuration(); //hibernate5
for(Map.Entry<String, String> entry : prop.entrySet()) {
config.setProperty(entry.getKey(), entry.getValue());
}
if(namingStrategy!=null){
configuration.setNamingStrategy(namingStrategy); //code which I think spoil application
}
if(annotatedEntityPackages!=null){
addAnnotatedClasses(config);
}
sessionFactory = config.configure().buildSessionFactory();
} catch (final HibernateException e) {
LOGGER.error("SessionFactory creation failed", e);
}
和
namingStrategy
放置者:
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy"/>
</property>
我已经尝试过发表评论了
configuration.setNamingStrategy(namingStrategy);
。我尝试了 configuration.setPhysicalNamingStrategy(PhysicalNamingStrategyImpl.INSTANCE);
但也尝试过 CamelCase
、UpperCase
等,每次错误都是一样的。无论我对这个 namingStrategy
类做什么都不会被映射。
示例类:
public class UpperCaseNamingStrategy extends PhysicalNamingStrategyStandardImpl {
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
return context.getIdentifierHelper().toIdentifier(
StringUtils.upperCase(name.getText(), Locale.ENGLISH));
}
@Override
public Identifier toPhysicalCatalogName(final Identifier name, final JdbcEnvironment context) {
return context.getIdentifierHelper().toIdentifier(
StringUtils.upperCase(name.getText(), Locale.ENGLISH));
}
@Override
public Identifier toPhysicalSchemaName(final Identifier name, final JdbcEnvironment context) {
return context.getIdentifierHelper().toIdentifier(
StringUtils.upperCase(name.getText(), Locale.ENGLISH));
}
@Override
public Identifier toPhysicalSequenceName(final Identifier name, final JdbcEnvironment context) {
return context.getIdentifierHelper().toIdentifier(
StringUtils.upperCase(name.getText(), Locale.ENGLISH));
}
@Override
public Identifier toPhysicalTableName(final Identifier name, final JdbcEnvironment context) {
return context.getIdentifierHelper().toIdentifier(
StringUtils.upperCase(name.getText(), Locale.ENGLISH));
}
}
但我仍然可以在日志中看到: org.hibernate.MappingException:表 X 中的关联引用未映射的类:Y 在 org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:709) 在 org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:746) 在repository.legacy.HibernateSessionManager.reloadHibernateSessionFactoryFromConf
那么
org.hibernate.cfg.ImprovedNamingStrategy
在 hibernate 5 中的实现是什么呢?
@编辑
其实我用的是:
public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl implements Serializable {
public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();
@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());
}
protected 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().toLowerCase(Locale.ROOT);
}
}
并完全删除:
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy"/>
</property>
但我不认为这是正确的解决方案,因为我可以在运行时看到很多问题。
尝试以下操作:
正确配置:
// 设置物理和隐式命名策略 config.setPhysicalNamingStrategy(new PhysicalNamingStrategyImpl()); config.setImplicitNamingStrategy(ImplicitNamingStrategyLegacyJpaImpl.INSTANCE);
检查实体映射:
Ensure that all your entities are correctly annotated with @Entity and that all entity classes are registered in the configuration
(即在 addAnnotatedClasses(config) 中列出或通过 config.addPackage("com.example") 列出)。
当 Hibernate 找不到实体或尝试映射与不存在的类的关联时,经常会出现您看到的错误。
仔细检查域模型中的映射(表、列和关联)是否正确。
PhysicalNamingStrategy
示例:@Table(name = "USER_ACCOUNT")
并且您的策略将 userAccount 转换为 user_account,除非该表在数据库中确实名为 USER_ACCOUNT,否则您将遇到问题。
更新代码:
private void reloadHibernateSessionFactoryFromConf(Map<String, String> prop) {
try {
sessionFactory = null;
Configuration config = new Configuration(); //hibernate5
// Set properties
for (Map.Entry<String, String> entry : prop.entrySet()) {
config.setProperty(entry.getKey(), entry.getValue());
}
// Set naming strategies
config.setPhysicalNamingStrategy(new PhysicalNamingStrategyImpl());
config.setImplicitNamingStrategy(ImplicitNamingStrategyLegacyJpaImpl.INSTANCE);
// Add annotated classes
if (annotatedEntityPackages != null) {
addAnnotatedClasses(config);
}
// Build session factory
sessionFactory = config.configure().buildSessionFactory();
} catch (final HibernateException e) {
LOGGER.error("SessionFactory creation failed", e);
}
}