Something similar to this question but OP there not mentioned that whether they creating LocalContainerEntityManagerFactoryBean .
Spring not injecting @Value or @Autowired annotated variables in PhysicalNamingStrategy Implementations:
@Configuration
public class SchemaPhysicalNamingStrategy extends CamelCaseToUnderscoresNamingStrategy {
@Value(value = "${spring.jpa.hibernate.default_schema}")
private String schemaName;
@Value(value = "${spring.jpa.hibernate.default_catalog}")
private String catalogName;
/**
* @param identifier
* @param jdbcEnvironment
* @return
*/
@Override
public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
if (isNull(identifier)) {
identifier = toIdentifier(this.schemaName);
}
return super.toPhysicalSchemaName(identifier, jdbcEnvironment);
}
@Override
public Identifier toPhysicalCatalogName(
Identifier identifier, JdbcEnvironment jdbcEnvironment) {
if (isNull(identifier)) {
identifier = toIdentifier(this.catalogName);
}
return super.toPhysicalCatalogName(identifier, jdbcEnvironment);
}
}
Below is one of the two LocalContainerEntityManagerFactoryBean objects which needs customised physical naming strategy.
@Bean(name = "integrationEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean integrationEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder.dataSource(integrationDataSource())
.packages("xx.xx.xx.xxxx.entity")
.properties(jpaProperties())
.build();
}
protected Map<String, Object> jpaProperties() {
return of(
"hibernate.physical_naming_strategy", SchemaPhysicalNamingStrategy.class.getName());
}
Issue is - @Value and @Autowired are not working on SchemaPhysicalNamingStrategy as spring creates instance using reflection. Can't add it to constructor as spring calls constructor without params using reflection. One option is to create SessionFactory bean and set on it but that will be overkill. Please help.
CodePudding user response:
Documentation says following:
Hibernate supports using the following integrations as managed beans:
- jakarta.persistence.AttributeConverter
- Jakarta Persistence "entity listener" classes
- org.hibernate.type.descriptor.jdbc.JdbcType
- org.hibernate.type.descriptor.java.BasicJavaType
- org.hibernate.type.descriptor.java.MutabilityPlan
- org.hibernate.usertype.UserType
- org.hibernate.usertype.UserCollectionType
- org.hibernate.metamodel.EmbeddableInstantiator
- org.hibernate.envers.RevisionListener
- org.hibernate.id.IdentifierGenerator
Since Hibernate do not recognise naming strategies as managed beans you need to pass them as instances to property map, for example:
@Bean(name = "integrationEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean integrationEntityManagerFactory(
EntityManagerFactoryBuilder builder
SchemaPhysicalNamingStrategy namingStrategy) {
return builder.dataSource(integrationDataSource())
.packages("xx.xx.xx.xxxx.entity")
.properties(jpaProperties(namingStrategy))
.build();
}
protected Map<String, Object> jpaProperties(PhysicalNamingStrategy namingStrategy) {
return of("hibernate.physical_naming_strategy", namingStrategy);
}