The JPA standard allows to hardly define a concrete schema for tables/entites via annotations (for example @Table). For my project was necessary to modify these shema names according to configuration on the realtime, just before EntityManagerFactory is created. Generally, the Hibernate version 4.3.7 provides for a db-to-java name mapping special interface org.hibernate.cfg.naming.NamingStrategyDelegate.
This interface provides lots of nice method for define a mapping between JPA objects names and db objects names, but one thing is missing - schema names customization.
Extending interface
For assurance of backward compatibility, I decided to create new interface as extended existing interface:
package org.hibernate.cfg.naming;
Modification of internal behavior of hibernate was not easy. All names modifications is present in very extensive class org.hibernate.cfg.AnnotationBinder. This class contains cca 2800 lines of code and really needs to be refactored :). I added this code fragment on multiple places:
NamingStrategyDelegate n =
mappings.getNamingStrategyDelegator().getNamingStrategyDelegate(false);
if (n instanceof ExtendNamingStrategyDelegate) {
schema = ((ExtendNamingStrategyDelegate) n).determineSchemaName(schema);
if (schema == null) {
schema = "";
}
}
package org.hibernate.cfg.naming;
public interface ExtendNamingStrategyDelegate extends NamingStrategyDelegate {
public String determineSchemaName(String schemaName);
}
Modification of internal behavior of hibernate was not easy. All names modifications is present in very extensive class org.hibernate.cfg.AnnotationBinder. This class contains cca 2800 lines of code and really needs to be refactored :). I added this code fragment on multiple places:
NamingStrategyDelegate n =
mappings.getNamingStrategyDelegator().getNamingStrategyDelegate(false);
if (n instanceof ExtendNamingStrategyDelegate) {
schema = ((ExtendNamingStrategyDelegate) n).determineSchemaName(schema);
if (schema == null) {
schema = "";
}
}
If you want to see whole class, please download sourcecode.
Patching of original hibernate
The Hibernate framework is opensource and for building purposes is used the Gradle system. Unfortunately, I haven't any knowledges about Gradle and also our processes in company are hardly maven-oriented. I've decided to do it "dirty" way with 2 maven projects.
- hibernate-core-patch (version 4.3.7.1) - contains my created class ExtendNamingStrategyDelegate and modified AnnotationBinder only. Project version 4.3.7.1 defines that patch is based on hibernate 4.3.7.
- hibernate-core (version 4.3.7.1-Patched)- Combination of original hibernate binaries (hibernate-core version 4.3.7) and forced injection of my modifications (hibernate-core-patch 4.3.7.1). This project does not contain any java code and it is defined as a integrator for binaries via maven-dependency-plugin.
Using of patch
After building and installing patched hibernate-core project, Use in your project patched version of hibernate-core instead of original (replace version 4.3.7 with 4.3.7.1-Patched).For using NamingStrategyDelegate, please read original documentation
https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch03.html#configuration-namingstrategy
With difference that you will use ExtendedNamingStrategyDelegate interface.