Note that this code does work with plain Spring but not with Spring Boot(v1.3.3), is there something i\'m missing because this is imported from a spring app that works. The
SINCE SPRING-BOOT 1.4
Starting from 1.4, because of the switch to Hibernate 5, the naming strategy has been updated to SpringPhysicalNamingStrategy
which should be very close to 1.3 defaults.
See also:
PREVIOUS VERSION
Spring Boot provides the ImprovedNamingStrategy as default naming strategy, which makes Hibernate search for a team_id
column (inferred from the int teamId
field). As this column doesn't exist in your table, that's the cause of the error. From the Hibernate docs:
An improved naming strategy that prefers embedded underscores to mixed case names
You've got two options:
Provide the column name explicitly as @Column(name="teamId")
. There used to be a bug with this in early Boot versions, not anymore.
Change the naming strategy in the Spring Boot properties and tell it to use the EJB3NamingStrategy, which doesn't convert camelCase to snake_case, but keeps it as it is.
This worked for me with spring boot 1.4.0 and hibernate entitymanager 4.3.8.Final
application.properties
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
If you are using Spring Boot 2.0.2 and Hibernate 5.3.4 then setting the following property will fix the issue.
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
application.properties
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.DefaultComponentSafeNamingStrategy
the above properties work for me. hibernate 4.3.11.Final spring boot 1.4.2.RELEASE
Below strategy worked for me
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.DefaultComponentSafeNamingStrategy
with the late version :
spring-boot-starter-data-jpa: ➡ 1.5.2.RELEASE
hibernate-core:5.0.12.Final
this class
PhysicalNamingStrategyStandardImpl
needs to be extended and added to hibernate properties.
Here is a full working version
public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl implements Serializable {
public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
String nameModified;
// Do whatever you want with the name modification
return new Identifier(nameModified, name.isQuoted());
}
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
String nameModified;
// Do whatever you want with the name modification
return new Identifier(nameModified, name.isQuoted());
}
Linking it to hibernate should be done like this when configuring the datasource.
properties.put("hibernate.physical_naming_strategy", "my.Package.PhysicalNamingStrategyImpl");
here is a full working version of datasource config
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
basePackages = { "com.xxxxxx.repository" }
)
public class SharedDataSourceConfig {
@Value("${startup.ddl-auto}")
String hbm2ddl;
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties("spring.datasource.shared")
public DataSource customerDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSource") DataSource dataSource) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", hbm2ddl);
properties.put("hibernate.physical_naming_strategy", "my.package.PhysicalNamingStrategyImpl");
return builder
.dataSource(dataSource)
.packages(PackageScannerHelper.getPackagesToScan())
.persistenceUnit("shared")
.properties(properties)
.build();
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("entityManagerFactory") EntityManagerFactory
entityManagerFactory
) {
return new JpaTransactionManager(entityManagerFactory);
}
}