IntelliJ IDEA에서 Gradle 변경 반영하기

IntelliJ IDEA에서 Gradle 변경 반영하기

IDEA에서 Gradle 프로젝트로 작업하다보면 dependencies 변경 같은 것이 반영이 안될 때가 있습니다.

라이브러리 버전을 바꾸던가 외부에서 git branch를 변경했다던가 등등의 이유인데요.

이럴 때는 Gradle tool window에 있는 새로고침 버튼을 클릭하면 됩니다.

참고 - Synchronizing Changes in Gradle Project and IntelliJ IDEA Project

EOF

신고

Spring Boot : auto-configuration 그리고 debug

Spring Boot 애플리케이션의 auto-configuration 정보를 확인하거나 DEBUG 레벨의 로그를 확인하려면 아래와 같이 --debug-Ddebug 옵션을 주면 됩니다.

$ java -jar myapp.jar --debug

그리고 문서에서는 확인이 안되지만 applicaton.properties 파일에, 값 없이 debug 키를 선언해도 됩니다(debug: 혹은 debug=).

debug:
spring.datasource.url: jdbc:hsqldb:file:D:/tmp/hsqldb/scratchdb
spring.jpa.show-sql: true
spring.jpa.generate-ddl: true
spring.jpa.hibernate.ddl-auto: create

이렇게 debug 옵션을 주면 auto-configuration 정보와 사용 중인 framework, library 등의 DEBUG 레벨 로그를 확인할 수 있습니다.

아래는 --debug 옵션과 함께 Spring Data JPA 앱의 테스트케이스를 실행했을 때의 콘솔 로그입니다.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v1.3.0.BUILD-SNAPSHOT)

2015-04-17 13:17:28.927  INFO 5124 --- [           main] c.i.rt.execution.junit.JUnitStarter      : Starting JUnitStarter on envy-i7 with PID 5124 (started by kyutae.park in D:\dev\repos\spring-boot-data-jpa-javaworld)
2015-04-17 13:17:28.928 DEBUG 5124 --- [           main] o.s.boot.SpringApplication               : Loading source class sample.data.jpa.SampleDataJpaApplication
2015-04-17 13:17:29.243 DEBUG 5124 --- [           main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application.yaml' resource not found

    ..............
    .... 중략 ....
    ..............

Hibernate: alter table tb_person_02837_cars add constraint FK_enugsq5f3484moat7h2ggrf1a foreign key (tb_person_02837_id) references tb_person_02837
2015-04-17 13:17:43.191  INFO 5124 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete
2015-04-17 13:17:45.352 DEBUG 5124 --- [           main] utoConfigurationReportLoggingInitializer : 


=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:
-----------------

   AopAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.context.annotation.EnableAspectJAutoProxy,org.aspectj.lang.annotation.Aspect,org.aspectj.lang.reflect.Advice (OnClassCondition)
      - matched (OnPropertyCondition)

   AopAutoConfiguration.JdkDynamicAutoProxyConfiguration
      - matched (OnPropertyCondition)

   DataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)

   DataSourceAutoConfiguration.DataSourceInitializerConfiguration
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration
      - existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration#jdbcTemplate
      - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.JdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration#namedParameterJdbcTemplate
      - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.NonEmbeddedConfiguration
      - supported DataSource class found (DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition)
      - @ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourcePoolMetadataProvidersConfiguration.TomcatDataSourcePoolMetadataProviderConfiguration
      - @ConditionalOnClass classes found: org.apache.tomcat.jdbc.pool.DataSource (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration.TransactionManagementConfiguration
      - @ConditionalOnMissingBean (types: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration; SearchStrategy: all) found no beans (OnBeanCondition)

   GenericCacheConfiguration
      - Automatic cache type (CacheCondition)

   HibernateJpaAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.transaction.annotation.EnableTransactionManagement,javax.persistence.EntityManager (OnClassCondition)
      - found HibernateEntityManager class (HibernateJpaAutoConfiguration.HibernateEntityManagerCondition)

   HttpEncodingAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.filter.CharacterEncodingFilter (OnClassCondition)
      - matched (OnPropertyCondition)

   HttpEncodingAutoConfiguration#characterEncodingFilter
      - @ConditionalOnMissingBean (types: org.springframework.web.filter.CharacterEncodingFilter; SearchStrategy: all) found no beans (OnBeanCondition)

   HttpMessageConvertersAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.http.converter.HttpMessageConverter (OnClassCondition)

   HttpMessageConvertersAutoConfiguration#messageConverters
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.HttpMessageConverters; SearchStrategy: all) found no beans (OnBeanCondition)

   HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration
      - @ConditionalOnClass classes found: org.springframework.http.converter.StringHttpMessageConverter (OnClassCondition)

   HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration#stringHttpMessageConverter
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.StringHttpMessageConverter; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonAutoConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper,org.springframework.http.converter.json.Jackson2ObjectMapperBuilder (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration#jacksonObjectMapperBuilder
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonAutoConfiguration.JacksonObjectMapperConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper,org.springframework.http.converter.json.Jackson2ObjectMapperBuilder (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper
      - @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper (OnClassCondition)
      - matched (OnPropertyCondition)
      - @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found the following [jacksonObjectMapper] (OnBeanCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration#mappingJackson2HttpMessageConverter
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#entityManagerFactory
      - @ConditionalOnMissingBean (types: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#entityManagerFactoryBuilder
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilder; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#jpaVendorAdapter
      - @ConditionalOnMissingBean (types: org.springframework.orm.jpa.JpaVendorAdapter; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#transactionManager
      - @ConditionalOnMissingBean (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) found no beans (OnBeanCondition)

   JtaAutoConfiguration
      - @ConditionalOnClass classes found: javax.transaction.Transaction (OnClassCondition)
      - matched (OnPropertyCondition)

   MultipartAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.multipart.support.StandardServletMultipartResolver,javax.servlet.MultipartConfigElement (OnClassCondition)
      - matched (OnPropertyCondition)

   MultipartAutoConfiguration#multipartConfigElement
      - @ConditionalOnMissingBean (types: javax.servlet.MultipartConfigElement; SearchStrategy: all) found no beans (OnBeanCondition)

   MultipartAutoConfiguration#multipartResolver
      - @ConditionalOnMissingBean (types: org.springframework.web.multipart.MultipartResolver; SearchStrategy: all) found no beans (OnBeanCondition)

   NoOpCacheConfiguration
      - Automatic cache type (CacheCondition)

   PersistenceExceptionTranslationAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor (OnClassCondition)

   PersistenceExceptionTranslationAutoConfiguration#persistenceExceptionTranslationPostProcessor
      - @ConditionalOnMissingBean (types: org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; SearchStrategy: all) found no beans (OnBeanCondition)
      - matched (OnPropertyCondition)

   PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer
      - @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) found no beans (OnBeanCondition)

   RedisCacheConfiguration
      - Automatic cache type (CacheCondition)

   SimpleCacheConfiguration
      - Automatic cache type (CacheCondition)

   TransactionAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.transaction.support.TransactionTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)
      - @ConditionalOnSingleCandidate (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) found a primary candidate amongst the following [transactionManager] (OnBeanCondition)

   TransactionAutoConfiguration#transactionTemplate
      - @ConditionalOnMissingBean (types: org.springframework.transaction.support.TransactionTemplate; SearchStrategy: all) found no beans (OnBeanCondition)

   WebSocketAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,javax.websocket.server.ServerContainer (OnClassCondition)

   WebSocketAutoConfiguration.TomcatWebSocketConfiguration
      - @ConditionalOnClass classes found: org.apache.catalina.startup.Tomcat,org.apache.tomcat.websocket.server.WsSci (OnClassCondition)

   WebSocketAutoConfiguration.TomcatWebSocketConfiguration#websocketContainerCustomizer
      - @ConditionalOnMissingBean (names: websocketContainerCustomizer; SearchStrategy: all) found no beans (OnBeanCondition)


Negative matches:
-----------------

   ActiveMQAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.jms.ConnectionFactory,org.apache.activemq.ActiveMQConnectionFactory (OnClassCondition)

   AopAutoConfiguration.CglibAutoProxyConfiguration
      - @ConditionalOnProperty missing required properties spring.aop.proxy-target-class  (OnPropertyCondition)

   AtomikosJtaConfiguration
      - required @ConditionalOnClass classes not found: com.atomikos.icatch.jta.UserTransactionManager (OnClassCondition)

   BatchAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.batch.core.launch.JobLauncher (OnClassCondition)

   BitronixJtaConfiguration
      - required @ConditionalOnClass classes not found: bitronix.tm.jndi.BitronixContext (OnClassCondition)

   CacheAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.cache.CacheManager (OnClassCondition)
      - @ConditionalOnBean (types: org.springframework.cache.interceptor.CacheAspectSupport; SearchStrategy: all) found no beans (OnBeanCondition)

   CloudAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.cloud.config.java.CloudScanConfiguration (OnClassCondition)

   DataSourceAutoConfiguration.EmbeddedConfiguration
      - existing non-embedded database detected (DataSourceAutoConfiguration.EmbeddedDataSourceCondition)

   DataSourceAutoConfiguration.TomcatDataSourceJmxConfiguration
      - @ConditionalOnClass classes found: org.apache.tomcat.jdbc.pool.DataSourceProxy (OnClassCondition)
      - existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition)
      - @ConditionalOnProperty missing required properties spring.datasource.jmx-enabled  (OnPropertyCondition)

   DataSourcePoolMetadataProvidersConfiguration.CommonsDbcpPoolDataSourceMetadataProviderConfiguration
      - required @ConditionalOnClass classes not found: org.apache.commons.dbcp.BasicDataSource (OnClassCondition)

   DataSourcePoolMetadataProvidersConfiguration.HikariPoolDataSourceMetadataProviderConfiguration
      - required @ConditionalOnClass classes not found: com.zaxxer.hikari.HikariDataSource (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration#transactionManager
      - @ConditionalOnMissingBean (names: transactionManager; SearchStrategy: all) found the following [transactionManager] (OnBeanCondition)

   DeviceDelegatingViewResolverAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver (OnClassCondition)

   DeviceResolverAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.DeviceResolverHandlerInterceptor,org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver (OnClassCondition)

   DispatcherServletAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   EhCacheCacheConfiguration
      - required @ConditionalOnClass classes not found: net.sf.ehcache.Cache,org.springframework.cache.ehcache.EhCacheCacheManager (OnClassCondition)

   ElasticsearchAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.client.TransportClientFactoryBean,org.springframework.data.elasticsearch.client.NodeClientFactoryBean (OnClassCondition)

   ElasticsearchDataAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.core.ElasticsearchTemplate (OnClassCondition)

   ElasticsearchRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.repository.ElasticsearchRepository (OnClassCondition)

   EmbeddedServletContainerAutoConfiguration
      - not a web application (OnWebApplicationCondition)

   ErrorMvcAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   FacebookAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.facebook.connect.FacebookConnectionFactory (OnClassCondition)

   FallbackWebSecurityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.security.config.annotation.web.configuration.EnableWebSecurity (OnClassCondition)

   FlywayAutoConfiguration
      - required @ConditionalOnClass classes not found: org.flywaydb.core.Flyway (OnClassCondition)

   FreeMarkerAutoConfiguration
      - required @ConditionalOnClass classes not found: freemarker.template.Configuration,org.springframework.ui.freemarker.FreeMarkerConfigurationFactory (OnClassCondition)

   GroovyTemplateAutoConfiguration
      - required @ConditionalOnClass classes not found: groovy.text.markup.MarkupTemplateEngine (OnClassCondition)

   GsonAutoConfiguration
      - required @ConditionalOnClass classes not found: com.google.gson.Gson (OnClassCondition)

   GsonHttpMessageConvertersConfiguration
      - required @ConditionalOnClass classes not found: com.google.gson.Gson (OnClassCondition)

   GuavaCacheConfiguration
      - required @ConditionalOnClass classes not found: com.google.common.cache.CacheBuilder,org.springframework.cache.guava.GuavaCacheManager (OnClassCondition)

   GzipFilterAutoConfiguration
      - required @ConditionalOnClass classes not found: org.eclipse.jetty.servlets.GzipFilter (OnClassCondition)

   HazelcastCacheConfiguration
      - required @ConditionalOnClass classes not found: com.hazelcast.core.HazelcastInstance,com.hazelcast.spring.cache.HazelcastCacheManager (OnClassCondition)

   HornetQAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.jms.ConnectionFactory,org.hornetq.api.jms.HornetQJMSClient (OnClassCondition)

   HypermediaAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.hateoas.Resource,org.springframework.plugin.core.Plugin (OnClassCondition)

   IntegrationAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.integration.config.EnableIntegration (OnClassCondition)

   JCacheCacheConfiguration
      - required @ConditionalOnClass classes not found: javax.cache.Caching,org.springframework.cache.jcache.JCacheCacheManager (OnClassCondition)

   JacksonAutoConfiguration.JodaDateTimeJacksonConfiguration
      - required @ConditionalOnClass classes not found: org.joda.time.DateTime,com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer,com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat (OnClassCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2XmlHttpMessageConverterConfiguration
      - required @ConditionalOnClass classes not found: com.fasterxml.jackson.dataformat.xml.XmlMapper (OnClassCondition)

   JerseyAutoConfiguration
      - required @ConditionalOnClass classes not found: org.glassfish.jersey.server.spring.SpringComponentProvider (OnClassCondition)

   JmsAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.jms.core.JmsTemplate (OnClassCondition)

   JmxAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.jmx.export.MBeanExporter (OnClassCondition)
      - @ConditionalOnProperty expected 'true' for properties spring.jmx.enabled (OnPropertyCondition)

   JndiConnectionFactoryAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.jms.core.JmsTemplate (OnClassCondition)

   JndiDataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
      - @ConditionalOnProperty missing required properties spring.datasource.jndi-name  (OnPropertyCondition)

   JndiJtaConfiguration
      - @ConditionalOnClass classes found: org.springframework.transaction.jta.JtaTransactionManager (OnClassCondition)
      - JNDI environment is not available (OnJndiCondition)

   JpaBaseConfiguration.JpaWebConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   JpaRepositoriesAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.data.jpa.repository.JpaRepository (OnClassCondition)
      - matched (OnPropertyCondition)
      - @ConditionalOnMissingBean (types: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean,org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension; SearchStrategy: all) found the following [&personRepository, &reviewRepository, &cityRepository, &hotelRepository, &carRepository, org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension#0] (OnBeanCondition)

   LinkedInAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.linkedin.connect.LinkedInConnectionFactory (OnClassCondition)

   LiquibaseAutoConfiguration
      - required @ConditionalOnClass classes not found: liquibase.integration.spring.SpringLiquibase (OnClassCondition)

   MailSenderAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.mail.internet.MimeMessage (OnClassCondition)

   MessageSourceAutoConfiguration
      - No bundle found for spring.messages.basename: messages (MessageSourceAutoConfiguration.ResourceBundleCondition)

   MongoAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo (OnClassCondition)

   MongoDataAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo,org.springframework.data.mongodb.core.MongoTemplate (OnClassCondition)

   MongoRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo,org.springframework.data.mongodb.repository.MongoRepository (OnClassCondition)

   MustacheAutoConfiguration
      - required @ConditionalOnClass classes not found: com.samskivert.mustache.Mustache (OnClassCondition)

   RabbitAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.amqp.rabbit.core.RabbitTemplate,com.rabbitmq.client.Channel (OnClassCondition)

   ReactorAutoConfiguration
      - required @ConditionalOnClass classes not found: reactor.spring.context.config.EnableReactor,reactor.core.Environment (OnClassCondition)

   RedisAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.data.redis.connection.jedis.JedisConnection,org.springframework.data.redis.core.RedisOperations,redis.clients.jedis.Jedis (OnClassCondition)

   RepositoryRestMvcAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration (OnClassCondition)

   SecurityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.security.authentication.AuthenticationManager,org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter (OnClassCondition)

   SendGridAutoConfiguration
      - required @ConditionalOnClass classes not found: com.sendgrid.SendGrid (OnClassCondition)

   ServerPropertiesAutoConfiguration
      - not a web application (OnWebApplicationCondition)

   SitePreferenceAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor,org.springframework.mobile.device.site.SitePreferenceHandlerMethodArgumentResolver (OnClassCondition)

   SocialWebAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.connect.web.ConnectController,org.springframework.social.config.annotation.SocialConfigurerAdapter (OnClassCondition)

   SolrAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.solr.client.solrj.impl.HttpSolrServer,org.apache.solr.client.solrj.impl.CloudSolrServer (OnClassCondition)

   SolrRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.solr.client.solrj.SolrServer,org.springframework.data.solr.repository.SolrRepository (OnClassCondition)

   SpringDataWebAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.data.web.PageableHandlerMethodArgumentResolver,org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   ThymeleafAutoConfiguration
      - required @ConditionalOnClass classes not found: org.thymeleaf.spring4.SpringTemplateEngine (OnClassCondition)

   TwitterAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.twitter.connect.TwitterConnectionFactory (OnClassCondition)

   VelocityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.velocity.app.VelocityEngine,org.springframework.ui.velocity.VelocityEngineFactory (OnClassCondition)

   WebMvcAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet,org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   WebSocketAutoConfiguration.JettyWebSocketConfiguration
      - required @ConditionalOnClass classes not found: org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer (OnClassCondition)

   WebSocketAutoConfiguration.UndertowWebSocketConfiguration
      - required @ConditionalOnClass classes not found: io.undertow.websockets.jsr.Bootstrap (OnClassCondition)

   XADataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,javax.transaction.TransactionManager,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
      - @ConditionalOnBean (types: org.springframework.boot.jta.XADataSourceWrapper; SearchStrategy: all) found no beans (OnBeanCondition)


Exclusions:
-----------

    None



2015-04-17 13:17:45.388  INFO 5124 --- [           main] c.i.rt.execution.junit.JUnitStarter      : Started JUnitStarter in 23.914 seconds (JVM running for 45.382)
2015-04-17 13:17:45.461 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select count(city0_.id) as col_0_0_ from city city0_
Hibernate: select count(city0_.id) as col_0_0_ from city city0_
2015-04-17 13:17:45.468 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_, city0_.country as country2_0_, city0_.map as map3_0_, city0_.name as name4_0_, city0_.state as state5_0_ from city city0_ order by city0_.name asc limit ?
Hibernate: select city0_.id as id1_0_, city0_.country as country2_0_, city0_.map as map3_0_, city0_.name as name4_0_, city0_.state as state5_0_ from city city0_ order by city0_.name asc limit ?
2015-04-17 13:17:45.490 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select count(hotel0_.id) as col_0_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id where hotel0_.city_id=? group by hotel0_.id
Hibernate: select count(hotel0_.id) as col_0_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id where hotel0_.city_id=? group by hotel0_.id
2015-04-17 13:17:45.502 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select hotel0_.city_id as col_0_0_, hotel0_.name as col_1_0_, avg(cast(reviews1_.rating as double)) as col_2_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id inner join city city2_ on hotel0_.city_id=city2_.id where hotel0_.city_id=? group by hotel0_.id order by hotel0_.name asc limit ?
Hibernate: select hotel0_.city_id as col_0_0_, hotel0_.name as col_1_0_, avg(cast(reviews1_.rating as double)) as col_2_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id inner join city city2_ on hotel0_.city_id=city2_.id where hotel0_.city_id=? group by hotel0_.id order by hotel0_.name asc limit ?
2015-04-17 13:17:45.515 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
Hibernate: select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
2015-04-17 13:17:45.520  WARN 5124 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Warning Code: -1003, SQLState: 01003
2015-04-17 13:17:45.520  WARN 5124 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : warning: null value eliminated in set function
2015-04-17 13:17:45.528 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select hotel0_.id as id1_1_, hotel0_.address as address2_1_, hotel0_.city_id as city_id5_1_, hotel0_.name as name3_1_, hotel0_.zip as zip4_1_ from hotel hotel0_ where hotel0_.city_id=? and hotel0_.name=?
Hibernate: select hotel0_.id as id1_1_, hotel0_.address as address2_1_, hotel0_.city_id as city_id5_1_, hotel0_.name as name3_1_, hotel0_.zip as zip4_1_ from hotel hotel0_ where hotel0_.city_id=? and hotel0_.name=?
2015-04-17 13:17:45.530 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
Hibernate: select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
2015-04-17 13:17:45.537 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select review0_.rating as col_0_0_, count(review0_.id) as col_1_0_ from review review0_ where review0_.hotel_id=? group by review0_.rating order by review0_.rating DESC
Hibernate: select review0_.rating as col_0_0_, count(review0_.id) as col_1_0_ from review review0_ where review0_.hotel_id=? group by review0_.rating order by review0_.rating DESC
2015-04-17 13:17:45.543  INFO 5124 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7050ad86: startup date [Fri Apr 17 13:17:29 GMT+09:00 2015]; root of context hierarchy
2015-04-17 13:17:45.548  INFO 5124 --- [       Thread-1] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'

Process finished with exit code 0

조금 길지만 auto-configuration에 관한 내용을 찬찬히 읽어 보면 어떻게 앱이 자동 설정되었는지 확인할 수 있습니다.

EOF

신고

Spring Data JPA - LazyInitializationException

개요

요즘 Spring Boot 저장소에 있는 Spring Data JPA 샘플 프로젝트를 살펴 보고 있습니다.

테스트 코드를 작성하면서 하나하나 파악하고 있는데, OneToMany로 엮인 다른 엔티티의 목록을 가져오려고 하면 아래와 같은 오류가 발생합니다.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: kr.co.javaworld.jpa.domain.Person.cars, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
    at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
    at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:278)
    at org.hamcrest.collection.IsCollectionWithSize.featureValueOf(IsCollectionWithSize.java:21)
    at org.hamcrest.collection.IsCollectionWithSize.featureValueOf(IsCollectionWithSize.java:14)
    at org.hamcrest.FeatureMatcher.matchesSafely(FeatureMatcher.java:40)
    at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:12)
    at org.junit.Assert.assertThat(Assert.java:956)
    at org.junit.Assert.assertThat(Assert.java:923)
    at kr.co.javaworld.jpa.service.PersonRepositoryIntegrationTests.testFindCars(PersonRepositoryIntegrationTests.java:46)
    ..............
    .... 중략 ....
    ..............
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

늦은 초기화(Lazy initialization)에 관련된 예외 상황인데, 이에 대한 해결 방법을 정리해 봅니다.

예외가 발생하는 코드

아래의 테스트 코드를 실행하던 중 예외가 발생했습니다. testFindCars 메소드는 Person 객체를 하나 찾은 후, 다시 그 Person이 가진 Car 목록을 조회하는 테스트 코드입니다.

Person.getCars() 호출 후 목록(cars)의 크기를 얻으려고 하니까(assertThat(cars, hasSize(4))) 오류가 발생했습니다.

package kr.co.javaworld.jpa.service;

import kr.co.javaworld.jpa.domain.Car;
import kr.co.javaworld.jpa.domain.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.data.jpa.SampleDataJpaApplication;

import javax.transaction.Transactional;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class PersonRepositoryIntegrationTests {

    @Autowired
    PersonRepository repository;

    ..............
    .... 중략 ....
    ..............

    @Test
    public void testFindCars() {
        Person person = repository.findOne(1L);
        List<Car> cars = person.getCars();

        assertThat(cars, hasSize(4));
        assertThat(cars.get(0).getName(), is("Mercedes"));
    }
}

Person 엔티티의 코드입니다.
cars@OneToMany annotation이 붙어있을 뿐 특별한 점은 없습니다.

package kr.co.javaworld.jpa.domain;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "TB_PERSON_02837")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "PERSON_NAME", length = 100, unique = true, nullable = false)
    private String name;

    @OneToMany
    private List<Car> cars;

    ..............
    .... 중략 ....
    ..............

}

해결 방법

@OneToMany로 엮을 경우 JPA는 늦은 초기화를 통해 Personcars 목록을 가져오는게 기본 설정입니다. 즉, 위 코드의 @OneToMany annotation 선언은 @OneToMany(fetch = FetchType.LAZY)로 대체해도 동일합니다.

따라서 해결 방법은 간단합니다. 패치 타입을 FetchType.EAGER로 변경하여 늦은 초기화 대신 이른 초기화(Eager initialization)를 사용하면 됩니다.

아래 코드와 같이 @OneToMany(fetch = FetchType.EAGER)로 annotation 선언을 변경해 주면 오류가 사라집니다.

package kr.co.javaworld.jpa.domain;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "TB_PERSON_02837")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "PERSON_NAME", length = 100, unique = true, nullable = false)
    private String name;

    @OneToMany(fetch = FetchType.EAGER)
    private List<Car> cars;

    ..............
    .... 중략 ....
    ..............

}

다른 해결 방법

앞서의 해결 방법은 People 엔티티를 얻어 올 때는 언제나 Car 목록도 함께 가져오도록 강제합니다. 따라서 가끔씩만 Car 목록이 필요하다면 불필요한 메모리 낭비나 서버 성능 저하 등의 문제가 발생할 수 있습니다.

늦은 초기화를 사용하면서도 문제를 해결하려면 아래와 같이 트랜잭션을 Person.getCar() 호출 후 관련 동작을 완료할 때까지 유지하면 됩니다.

아래에서는 testFindCars 메소드에 @Transactional annotation을 붙여서 메소드 전체를 하나의 트랜잭션으로 감쌌습니다.

실무에서는 서비스 클래스의 메소드 단위로 트랜잭션을 잡아 주거나, 뷰 단의 서블릿 필터에서 UserTransaction을 이용하여 요청 단위로 트랜잭션을 처리하는 방법을 사용하면 됩니다.

package kr.co.javaworld.jpa.service;

import kr.co.javaworld.jpa.domain.Car;
import kr.co.javaworld.jpa.domain.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.data.jpa.SampleDataJpaApplication;

import javax.transaction.Transactional;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class PersonRepositoryIntegrationTests {

    @Autowired
    PersonRepository repository;

    ..............
    .... 중략 ....
    ..............

    @Test
    @Transactional
    public void testFindCars() {
        Person person = repository.findOne(1L);
        List<Car> cars = person.getCars();

        assertThat(cars, hasSize(4));
        assertThat(cars.get(0).getName(), is("Mercedes"));
    }
}

EOF

신고

Eclipse Mylyn을 통해 GitLab 이슈 사용하기

소개

GitLab은 프로젝트 별로 이슈 관리를 제공합니다.
직접 웹사이트에서 이슈를 관리하는 건 조금 불편한 부분이 있어서 Eclipse Mylyn을 통해서 사용해봅니다.

Mylyn Gitlab Connector 설치

Eclipse에서 GitLab 커넥터를 제공하지 않기 때문에 따로 설치가 필요합니다.
여기에서는 Mylyn Gitlab Connector를 설치해봅니다.

Eclipse의 Help > Install New Software를 클릭합니다.

소프트웨어 사이트를 추가하기 위해서 우상단의 Add를 클릭합니다.

Add Repository 창이 뜨면 Name에는 Mylyn Gitlab Connector, Location에는 http://pweingardt.github.com/mylyn-gitlab을 입력합니다.

설치 가능한 소프트웨어 목록에서 Mylyn Connectors를 체크합니다.

Next를 클릭해서 계속 진행합니다.

Mylyn Gitlab Connector는 EPL 라이센스로 제공됩니다. 라이센스에 동의합니다.

서명이 없는 콘텐츠를 포함한 소프트웨어를 설치하려 한다는 경고입니다.

설치가 완료되면 Eclipse를 재시작합니다.

Mylyn에 GitLab 연결

Task List 뷰에서 를 클릭한 후 다시 Add Repository를 클릭합니다.

Task List 뷰는 Window > Show View에서 선택해서 열 수 있습니다.

Add Task Repository 창에서 Gitlab issues를 선택하고 Next를 클릭합니다.

Server에는 http로 시작하는 Gitlab 저장소 주소를 넣습니다.
Label에는 저장소 이름을 입력합니다.
GitLab User ID와 Password를 입력한 후 꼭 Save Password를 체크합니다. 연동할 때마다 암호을 입력 받는 기능을 아직 지원하지 않습니다.

입력을 완료한 후 Finish를 클릭합니다.

Add new query 창이 뜨면서 Task List를 조회할 질의를 지금 작성할 것인지를 묻습니다.

Query title에는 All을 입력하고 모든 State를 선택해서 프로젝트의 모든 이슈를 가져오도록 설정했습니다.

질의 작성을 완료하면 Task List에서 GitLab의 모든 이슈를 볼 수 있습니다.

이슈를 더블 클릭하면 편집기에서 이슈 내용을 수정하거나 댓글을 다는 등의 동작을 할 수 있습니다.

New Task를 클릭해서 새 이슈(Task)를 등록할 수도 있습니다.

이슈(Task)를 저장할 Repository를 선택합니다. Task Repository 생성 시 지정한 Label을 선택하면 됩니다.

새 이슈(Task)를 입력하는 화면이 열립니다.

EOF

신고

PuTTY로 Amazon EC2 인스턴스 접속하기

PuTTYgen 내려 받기

EC2 인스턴스에 PuTTY를 이용해 접속하려면, Key Pair 파일(.pem)을 .ppk 파일로 변환해야 합니다.

.ppk 파일은 PuTTYgen(PuTTY Key Generator)을 이용해서 생성 할 수 있습니다.
아래 링크에서 PuTTYgen을 내려받습니다.

PuTTY Download Page

바로 내려받기

설치 없이 바로 실행하여 사용할 수 있습니다.

Amazon Key Pair(.pem)를 PuTTY Private Key File(.ppk)로 변환

PuTTYgen을 실행한 후 상단 메뉴에서, Conversions > Import key를 클릭합니다.

Load private key 창이 열리면 .pem 파일을 찾아서 엽니다.

Key Pair에 대한 정보가 로딩되면 Save private key를 클릭합니다.

passphrase 없이 키를 저장할 것인지 물어봅니다. 예(Y)를 클릭하여 수락합니다.

Save private key as 창이 열리면, 원하는 경로와 이름을 지정한 후 ppk 파일을 저장합니다.
여기에서는 바탕화면에 aws_hbase.ppk로 저장했습니다.

PuTTY에서 ppk 파일 사용하기

PuTTY 설정창(PuTTY Configuration)의 Category에서 Connection > SSH > Auth로 이동한 후, Browse를 클릭합니다.

위에서 저장한 ppk 파일을 선택합니다.

ppk 파일 선택이 완료됐습니다.

이제 Session Category로 이동한 후 Host Name에 EC2 인스턴스의 주소를 입력한 후 Open을 클릭하여 접속하면 됩니다.

신고