Home > database >  @Value or @Autowired annotations not working with custom Physical Naming Strategy
@Value or @Autowired annotations not working with custom Physical Naming Strategy

Time:01-31

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);
}
  • Related