[SPRING] 봄 - 최대 절전 모드 5 명명 전략 구성
SPRING봄 - 최대 절전 모드 5 명명 전략 구성
postgresql 데이터베이스와 봄 + 최대 절전 모드 프레임 워크를 사용하여 응용 프로그램을 작성하고 있습니다.
4.1.5.RELEASE에서 4.2.0.RELEASE 버전으로 스프링 프레임 워크를 업그레이드하고 4.3.7에서 최종 절전 프레임 워크를 5.0.0으로 업그레이드했습니다. 최종 버전.
업그레이드가 끝나면 NamingStrategy에 문제가 있습니다. postgresql 데이터베이스에서 테이블 열 이름은 밑줄로 구분하여 소문자로 표시되며, 응용 프로그램 계층에서는 bean 속성이 camelcase에 있습니다.
이전 버전의 스프링 구성 파일입니다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="fms" />
<bean id="microFmsDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="***" />
<property name="username" value="***" />
<property name="password" value="***" />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="true" />
<property name="testWhileIdle" value="true" />
<property name="validationQuery" value="select 1" />
<property name="initialSize" value="5" />
<property name="minIdle" value="10" />
<property name="maxIdle" value="100" />
<property name="maxActive" value="100" />
<property name="removeAbandoned" value="true" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="microFmsDataSource"/>
<property name="packagesToScan">
<list>
<value>fms</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider" />
<entry key="hibernate.hbm2ddl.auto" value="validate" />
<entry key="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<entry key="hibernate.show_sql" value="true" />
<entry key="hibernate.format_sql" value="true" />
<entry key="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
</map>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
업그레이드 후 NamingStrategy 구성이 변경되었습니다.
<entry key="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
이렇게 :
<entry key="hibernate.implicit_naming_strategy" value="***" />
hibernate javadoc에 나열된 모든 변형을 시험해 보았다 : https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/cfg/AvailableSettings.html#IMPLICIT_NAMING_STRATEGY
그러나 성공하지 못했습니다.
당신은 Hibernate 5에서 ImprovedNamingStrategy의 대안이 무엇인지 말해 줄 수 있습니까? 그리고 작동하는 설정 예제를 제공합니까?
해결법
-
==============================
1.솔루션을 찾은 것 같습니다.
솔루션을 찾은 것 같습니다.
내 목표를 달성하기 위해 hibernate.implicit_naming_strategy 대신 hibernate.physical_naming_strategy 구성을 사용했습니다.
필자는 원래 ImprovedNamingStrategy 클래스의 기능 중 일부를 시뮬레이트하는 PhysicalNamingStrategy 인터페이스의 구현을 만들었습니다.
package fms.util.hibernate; import org.apache.commons.lang.StringUtils; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.PhysicalNamingStrategy; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; public class ImprovedNamingStrategy implements PhysicalNamingStrategy { @Override public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnv) { return convert(identifier); } @Override public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) { return convert(identifier); } @Override public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnv) { return convert(identifier); } @Override public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnv) { return convert(identifier); } @Override public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnv) { return convert(identifier); } private Identifier convert(Identifier identifier) { if (identifier == null || StringUtils.isBlank(identifier.getText())) { return identifier; } String regex = "([a-z])([A-Z])"; String replacement = "$1_$2"; String newName = identifier.getText().replaceAll(regex, replacement).toLowerCase(); return Identifier.toIdentifier(newName); } }
이 클래스를 만든 후에 구성을 다음으로 변경했습니다.
<entry key="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
이에:
<entry key="hibernate.physical_naming_strategy" value="fms.util.hibernate.ImprovedNamingStrategy" />
이제 모든 것이 올바르게 작동합니다.
이 솔루션은 ImprovedNamingStrategy의 작은 부분만을 다룹니다. 내 프로젝트에서 테이블 매핑 및 조인 매핑을 위해 항상 테이블의 이름을 지정하거나 명시 적으로 열을 조인합니다. 필자는 열 이름에 대해서만 암시 적 이름 변환을 사용합니다. 그래서이 간단한 해결책은 나에게 받아 들일 만했다.
다음은 Spring 구성 파일의 전체 예제이다.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:component-scan base-package="fms" /> <bean id="microFmsDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="org.postgresql.Driver" /> <property name="url" value="***" /> <property name="username" value="***" /> <property name="password" value="***" /> <property name="testOnBorrow" value="true" /> <property name="testOnReturn" value="true" /> <property name="testWhileIdle" value="true" /> <property name="validationQuery" value="select 1" /> <property name="initialSize" value="5" /> <property name="minIdle" value="10" /> <property name="maxIdle" value="100" /> <property name="maxActive" value="100" /> <property name="removeAbandoned" value="true" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="microFmsDataSource"/> <property name="packagesToScan"> <list> <value>fms</value> </list> </property> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> <property name="jpaPropertyMap"> <map> <entry key="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider" /> <entry key="hibernate.hbm2ddl.auto" value="validate" /> <entry key="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> <entry key="hibernate.show_sql" value="true" /> <entry key="hibernate.format_sql" value="true" /> <entry key="hibernate.physical_naming_strategy" value="fms.util.hibernate.ImprovedNamingStrategy" /> </map> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
이 솔루션이 누군가에게 도움이되기를 바랍니다. :)
-
==============================
2.이 작품은 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/hibernate5/LocalSessionFactoryBean.html에서 구할 수 있습니다.
이 작품은 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/hibernate5/LocalSessionFactoryBean.html에서 구할 수 있습니다.
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <!-- convert aaBb to aa_bb --> <property name="PhysicalNamingStrategy"> <bean class="fms.util.hibernate.ImprovedNamingStrategy" /> </property> <!-- convert aa_bb to aaBb --> <property name="ImplicitNamingStrategy"> <bean class="org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl" /> </property> ... </bean>
-
==============================
3.Java Config Solution을 원하는 누구나
Java Config Solution을 원하는 누구나
hibernate.ejb.naming_strategy 속성은 Hibernate 5.X에서 두 부분으로 나뉘어 보인다.
hibernate.physical_naming_strategy
hibernate.implicit_naming_strategy
Spring은이를 위해 SpringImplicitNamingStrategy와 SpringPhysicalNamingStrategy를 제공한다.
여기 내 접근 방식입니다 :
import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; 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; @Configuration @DependsOn("myDataSource") @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef = "myEntityManagerFactory", basePackages={"com.myapp.repo"}, transactionManagerRef="myTransactionManager" ) public class MyJpaConfig { private Map<String, Object> properties; public MyJpaConfig() { properties = new HashMap<>(); properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName()); properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName()); } @Bean(name = "myEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("systemDataSource") DataSource dataSource) { LocalContainerEntityManagerFactoryBean build = builder.dataSource(dataSource) .packages("com.myapp.entity") .properties(properties) .build(); return build; } @Bean(name = "myTransactionManager") public PlatformTransactionManager myTransactionManager( @Qualifier("myEntityManagerFactory") EntityManagerFactory myEntityManagerFactory) { return new JpaTransactionManager(myEntityManagerFactory); } }
-
==============================
4.나는 똑같은 문제가 있었다. 스프링 부트에서 기본 구현으로 수정했습니다.
나는 똑같은 문제가 있었다. 스프링 부트에서 기본 구현으로 수정했습니다.
<property name="hibernate.implicit_naming_strategy" value="org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy" /> <property name="hibernate.physical_naming_strategy" value="org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy" />
-
==============================
5.이 시도:
이 시도:
@Bean public LocalSessionFactoryBean getSessionFactory() { LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean(); localSessionFactoryBean.setDataSource(getDataSource()); localSessionFactoryBean.setHibernateProperties(getHibernateProperties()); localSessionFactoryBean.setPackagesToScan(new String[]{"com.xxx.pojo"}); // -----important----- localSessionFactoryBean.setPhysicalNamingStrategy(new CustomNamingStrategy()); return localSessionFactoryBean; } public class CustomNamingStrategy extends PhysicalNamingStrategyStandardImpl {***
-
==============================
6.나에게 맞는 풀 스프링 설정 :
나에게 맞는 풀 스프링 설정 :
<property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="${db.platform}"/> <property name="generateDdl" value="false"/> </bean> </property> <property name="jpaProperties"> <props> <!--<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>--> <prop key="hibernate.implicit_naming_strategy">org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl</prop> <prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto:validate}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop> <prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments:false}</prop> <prop key="hibernate.id.new_generator_mappings">${hibernate.id.new_generator_mappings:true}</prop> <prop key="hibernate.enable_lazy_load_no_trans">${hibernate.enable_lazy_load_no_trans:true}</prop> <prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth:1}</prop> <prop key="hibernate.default_batch_fetch_size">${hibernate.default_batch_fetch_size:16}</prop> </props> </property> </bean>
from https://stackoverflow.com/questions/32165694/spring-hibernate-5-naming-strategy-configuration by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 mvc에서 컨트롤러에서 아약스로 객체를 반환하는 법 (0) | 2018.12.20 |
---|---|
[SPRING] REST 템플릿을 사용하여 서버에서 대용량 파일 다운로드 Java Spring MVC (0) | 2018.12.19 |
[SPRING] Spring Boot에서 HTTP OPTIONS 요청을 처리하는 방법은 무엇입니까? (0) | 2018.12.19 |
[SPRING] 페이징이있는 Spring-Data FETCH JOIN이 작동하지 않습니다. (0) | 2018.12.19 |
[SPRING] JPA EntityManager 세션 무효화 (0) | 2018.12.19 |