Reputation: 5727
I am migrating application from Hibernate 4 to Hibernate 5. I can't win with naming strategy. Of course I have already read: hibernate ImprovedNamingStrategy overrides Table name in entity and ImprovedNamingStrategy no longer working in Hibernate 5
In hibernate.cfg.xml
I have both:
<mapping resource="com/ubs/investor/cpss/domain/BonusHis.hbm.xml"/>
<mapping resource="com/ubs/investor/cpss/domain/Instrument.hbm.xml"/>
I already changed AnnotationConfiguration
to Configuration
and now I have:
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);
}
and namingStrategy
was put by:
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy"/>
</property>
I already tried to comment configuration.setNamingStrategy(namingStrategy);
at all. I tried configuration.setPhysicalNamingStrategy(PhysicalNamingStrategyImpl.INSTANCE);
but also CamelCase
, UpperCase
etc. and everytime error is the same. Whatever I do with this namingStrategy
class won't be mapped.
Example class:
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));
}
}
but still I can see in logs:
org.hibernate.MappingException: An association from the table BONUS_HIS refers to an unmapped class: domain.Instrument at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:709) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:746) at repository.legacy.HibernateSessionManager.reloadHibernateSessionFactoryFromConf
So what is implementation of org.hibernate.cfg.ImprovedNamingStrategy
in hibernate 5?
@Edit
Actually I used:
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());
}
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);
}
}
and completely removed:
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy"/>
</property>
but I don't think it's correct solutions because I can still see: org.hibernate.MappingException: An association from the table BONUS_HIS refers to an unmapped class: domain.Instrument
Upvotes: 0
Views: 121
Reputation: 5727
When using a mixed approach with annotations and XML, it is crucial to follow the correct order for creating the SessionFactory to avoid issues. The correct sequence is as follows:
Initialize the Configuration object:
Configuration config = new Configuration();
Add the annotated classes:
addAnnotatedClasses(config);
Build the SessionFactory:
sessionFactory = config.buildSessionFactory();
If this order is not followed, the XML configurations may override the annotations, leading to potential conflicts and errors.
Upvotes: 0
Reputation: 1173
Try following:
Correct Configuration:
// Set the Physical and Implicit Naming Strategies config.setPhysicalNamingStrategy(new PhysicalNamingStrategyImpl()); config.setImplicitNamingStrategy(ImplicitNamingStrategyLegacyJpaImpl.INSTANCE);
Check Entity Mappings:
Ensure that all your entities are correctly annotated with @Entity and that all entity classes are registered in the configuration
(i.e., listed in addAnnotatedClasses(config) or via config.addPackage("com.example")).
The error you see often comes up when Hibernate cannot find an entity or tries to map an association with a non-existent class.
Double-check that your mappings (tables, columns, and associations) are correct in your domain model.
PhysicalNamingStrategy
example: @Table(name = "USER_ACCOUNT")
and your strategy converts userAccount to user_account, you will encounter issues unless the table is indeed named USER_ACCOUNT in the database.
Updated Code:
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);
}
}
Upvotes: 1