====== Spring Boot And JPA ======
* [[springframework:springboot|SpringBoot]] & [[java:jpa|JPA]]
===== Open Entity Manager In View / Open Session In View (OSIV) 끄기 =====
* OSIV는 항상 끄자.
spring.jpa.open-in-view: false
* ''spring.jpa.open-in-view=false'' 는 ''JpaProperties'' 선언을 전혀 다르게 ''myapp.jpa'' 로 했더라도, **무조건 ''spring.jpa.open-in-view''로 해야한다.**
// SpringBoot 2.1 의 org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.JpaWebConfiguration 참조.
@ConditionalOnProperty(prefix = "spring.jpa", name = "open-in-view", havingValue = "true", matchIfMissing = true)
protected static class JpaWebConfiguration {
===== 별도 설정하기 =====
// 최상단에
@EnableConfigurationProperties
@EnableJpaRepositories(basePackageClasses = MyRepository.class,
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager")
...
@Bean
@ConfigurationProperties(prefix = "my.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create()
.type(org.apache.tomcat.jdbc.pool.DataSource.class) // Tomcat Pool 사용시
.build();
}
@Bean
@ConfigurationProperties(prefix = "my.jpa")
public JpaProperties jpaProperties() {
return new JpaProperties();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
Map hibernateProperties = jpaProperties().getHibernateProperties(dataSource());
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), hibernateProperties, null)
.dataSource(dataSource)
.persistenceUnit("mypersistenceunit")
.packages(EntityClasses.class) // entity class들의 위치
.build();
}
my:
jpa:
database-platform: MYSQL
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL57InnoDBDialect
default_batch_fetch_size: 16
id.new_generator_mappings: true
format_sql: true
show_sql: false
use_sql_comments: true
hbm2ddl.auto: update
===== Naming Strategy =====
* 현재 Spring boot 버전에 [[http://stackoverflow.com/questions/25283198/spring-boot-jpa-column-name-annotation-ignored|@Column(name="")이 안먹는 버그]]가 존재하는 것으로 보임.
* 그 외에 버그가 해결된 버전에서도 기본적으로 Spring 자체의 Naming Strategy를 사용하는데 이게 자동으로 이름을 변환해버리다 보니 의도에 맞지 않게 작동할 수 있음. 차라리 Hibernate 기본을 사용하고 항상 Table, Column 이름을 명시해주는게 편하다.
* [[https://github.com/spring-projects/spring-boot/issues/2129| @Column with name attribute not working property on entities]]
* 해결책은 naming strategy를 직접 지정해 줄 것
// Hibernate 4
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
// or
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
// Hibernate 5
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl