title: Spring, thymeleaf, JPA/hibernate, mysql UTF-8 characters persist in db
body: <p>I have problem with persisting polish PL-pl locale characters in mysql db.
  I know that is common issue, and out there in the internet is many solution to this. But I cant figure it out. I think I've tried everything.</p>
  
  <p><strong>All my web page correctly encode and display UTF-8 characters (static from html and from db)</strong></p>
  
  <p>Problem cames when I save somthing in db using form on my application. So I think it is tightly related to JDBC, JPA and hibernate.</p>
  
  <h2>Here is my configuration:</h2>
  
  <p><strong>application.properties</strong></p>
  
  <pre><code>#DB Properties:
  # Mysql
  db.driver=com.mysql.jdbc.Driver
  db.url=jdbc:mysql://localhost:3300/derp?characterEncoding=UTF-8
  hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
  db.username=root
  db.password=motorolaa835
  # H2
  #db.driver=org.h2.Driver
  #db.url=jdbc:h2:~/sts/derp/db/derp_db
  #hibernate.dialect=org.hibernate.dialect.H2Dialect
  #db.username=root
  
  #Hibernate Configuration:
  hibernate.show_sql=true
  hibernate.hbm2ddl.auto=update
  #hibernate.hbm2ddl.auto=create
  hibernate.connection.CharSet=utf8
  hibernate.connection.characterEncoding=utf8
  hibernate.connection.useUnicode=true
  services.entitymanager.packages.to.scan=com.derp
  cms.entitymanager.packages.to.scan=com.derp.cms.model
  common.entitymanager.packages.to.scan=com.derp.common.model
  procedure.entitymanager.packages.to.scan=com.derp.procedure.model
  </code></pre>
  
  <p><strong>Initializer</strong></p>
  
  <pre><code>  package com.derp.common.init;
  
  import javax.servlet.ServletContext;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRegistration.Dynamic;
  
  import org.springframework.web.WebApplicationInitializer;
  import org.springframework.web.context.ContextLoaderListener;
  import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
  import org.springframework.web.filter.CharacterEncodingFilter;
  import org.springframework.web.filter.HiddenHttpMethodFilter;
  import org.springframework.web.servlet.DispatcherServlet;
  
  public class Initializer implements WebApplicationInitializer {
  
  
      @Override
      public void onStartup(ServletContext servletContext) throws ServletException {
          AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
          ctx.register(WebAppConfig.class);
          ctx.register(ThymeleafConfig.class);
          servletContext.addListener(new ContextLoaderListener(ctx));
  
          ctx.setServletContext(servletContext);
  
          Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
          servlet.addMapping("/");
          servlet.setAsyncSupported(true);     
          servlet.setLoadOnStartup(1);
          // Allow to use Put and Delete method for REST architecture
          registerCharachterEncodingFilter(servletContext);
          registerHiddenFieldFilter(servletContext);
  
      }
  
  private void registerCharachterEncodingFilter(ServletContext aContext) {
      CharacterEncodingFilter cef = new CharacterEncodingFilter();
      cef.setForceEncoding(true);
      cef.setEncoding("UTF-8");
      aContext.addFilter("charachterEncodingFilter", cef).addMappingForUrlPatterns(null ,true, "/*");
  }
      private void registerHiddenFieldFilter(ServletContext aContext) {
          aContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*"); 
      }
  }
  </code></pre>
  
  <p><strong>WebAppConfig</strong></p>
  
  <pre><code>package com.derp.common.init;
  
  import java.util.Properties;
  
  import javax.annotation.Resource;
  import javax.sql.DataSource;
  
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.ComponentScan;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.context.annotation.PropertySource;
  import org.springframework.core.env.Environment;
  import org.springframework.http.MediaType;
  import org.springframework.jdbc.datasource.DriverManagerDataSource;
  import org.springframework.orm.hibernate4.HibernateTransactionManager;
  import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
  import org.springframework.transaction.annotation.EnableTransactionManagement;
  import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
  import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
  import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  
  //import com.derp.common.wicketView.HomePage;
  
  @Configuration
  @ComponentScan("com.derp")
  @EnableWebMvc
  @EnableTransactionManagement
  @PropertySource("classpath:application.properties")
  public class WebAppConfig extends WebMvcConfigurerAdapter {
  
      private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
      private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
      private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
      private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
  
      private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
      private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
      private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
      private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET = "hibernate.connection.CharSet";
      private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING = "hibernate.connection.characterEncoding";
      private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE = "hibernate.connection.useUnicode";
      private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES = "services.entitymanager.packages.to.scan";
      private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON = "common.entitymanager.packages.to.scan";
      private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS = "cms.entitymanager.packages.to.scan";
      private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_PROCEDURE = "procedure.entitymanager.packages.to.scan";
  
      @Resource
      private Environment env;
  
      @Bean
      public DataSource dataSource() {
          DriverManagerDataSource dataSource = new DriverManagerDataSource();
          dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
          dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
          dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
          dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
          return dataSource;
      }
  
      @Bean
      public LocalSessionFactoryBean sessionFactory() {
          LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
          sessionFactoryBean.setDataSource(dataSource());
          //sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
          sessionFactoryBean.setPackagesToScan(new String[] {
                  env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES),
                  env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON),
                  env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS),
                  env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_PROCEDURE)
                  });
          sessionFactoryBean.setHibernateProperties(hibProperties());
          return sessionFactoryBean;
      }
  
      private Properties hibProperties() {
          Properties properties = new Properties();
          properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
          properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
          properties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO));
          properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET));
          properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING));
          properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE));
          properties.put("jadira.usertype.autoRegisterUserTypes", "true");
          return properties;  
      }
  
      @Bean
      public HibernateTransactionManager transactionManager() {
          HibernateTransactionManager transactionManager = new HibernateTransactionManager();
          transactionManager.setSessionFactory(sessionFactory().getObject());
          return transactionManager;
      }
  
  
      @Override
      public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
          // Simple strategy: only path extension is taken into account
          configurer.favorPathExtension(true).
              ignoreAcceptHeader(true).
              useJaf(false).
              defaultContentType(MediaType.TEXT_HTML).
              mediaType("html", MediaType.TEXT_HTML).
              mediaType("xml", MediaType.APPLICATION_XML).
              mediaType("json", MediaType.APPLICATION_JSON);
      }
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
          registry.addResourceHandler("/img/**").addResourceLocations("/WEB-INF/img/*");
          registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/*");
          registry.addResourceHandler("/js/**").addResourceLocations("/WEB-INF/js/*");
          registry.addResourceHandler("/lib/**").addResourceLocations("/WEB-INF/lib/*");
      }
  }
  </code></pre>
  
  <p><strong>ThymeleafConfig</strong></p>
  
  <pre><code>package com.derp.common.init;
  
  
  import nz.net.ultraq.thymeleaf.LayoutDialect;
  
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.thymeleaf.spring4.SpringTemplateEngine;
  import org.thymeleaf.spring4.view.ThymeleafViewResolver;
  import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
  
  @Configuration 
  public class ThymeleafConfig {
  
      @Bean 
      public ServletContextTemplateResolver templateResolver() {
          ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
          resolver.setPrefix("/WEB-INF/view/");
          resolver.setSuffix(".html");
          resolver.setTemplateMode("HTML5");
          resolver.setOrder(1);
          resolver.setCacheable(false);
          return resolver;
      }
  
      @Bean 
      public SpringTemplateEngine templateEngine() {
          SpringTemplateEngine templateEngine = new SpringTemplateEngine();
          templateEngine.setTemplateResolver(templateResolver());
          templateEngine.addDialect(new LayoutDialect());
          //templateEngine.addDialect(new SpringStandardDialect());
          return templateEngine;
      }
  
      @Bean 
      public ThymeleafViewResolver thymeleafViewResolver() {
          ThymeleafViewResolver resolver = new ThymeleafViewResolver();
          resolver.setTemplateEngine(templateEngine());
          resolver.setCharacterEncoding("UTF-8");
          return resolver;
      }
  
  }
  </code></pre>
  
  <hr>
  
  <p>Edit</p>
  
  <p>There is no utf-8 characters when using this method on controller
  <strong>controller</strong></p>
  
  <pre><code>@RequestMapping(value="/test", method=RequestMethod.PUT)
  @ResponseBody
  public String ajaxTest() {
      return "Characters test: ęółąśżźćń";
  }
  </code></pre>
  
  <p><strong>and the javasscript ajax method</strong></p>
  
  <pre><code>  $(document).ready(function() {
        $('h1').click(function() {
            $.ajax({
                type: "PUT",
                url: "/derp/procedury/test",
                data: "none",
                success: function (response, status, xhr) {
                    showNotifications(status, xhr.responseText);
                },
                error: function (response, status, xhr) {
                    showNotifications('error', JSON.stringify(response));
                    showNotifications('error', status);
                    showNotifications('error', xhr);
                }
            });
        });
  </code></pre>
  
  <p>The result I get is:</p>
  
  <pre><code>  Characters test: ?�???????
  </code></pre>
  
  <hr>
  
  <p>Please give some helpful suggestions. Thanks in advance.</p>