3
respostas

Error Table casadocodigo_test.produto doesn't exit , Spring MVC II Módulo Spring Test Aula 7

Ao mudar a propriedade para create-drop o teste funciona perfeitamente , porém no exemplo da aula funciona tanto Spring Test quanto na aplicação com a propriedade DDL do hibernate setada update.

Alguém já passou por isso?

package br.com.casadocodigo.loja.conf;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@EnableTransactionManagement
public class JPAConfiguration {

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {

        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();

        factoryBean.setJpaVendorAdapter(vendorAdapter);
        factoryBean.setDataSource(dataSource);

        factoryBean.setJpaProperties(aditionalProperties());
        //factoryBean.setJpaProperties(aditionalProperties());
        //Configura o pacote de modelos para saber quais entidades o Hibernate irá gerenciar
        factoryBean.setPackagesToScan("br.com.casadocodigo.loja.models");


        return factoryBean;
    }

    @Bean
    @Profile("dev")
    public DataSource dataSource(){
        /*
         * Configura as informações do nosso DataSource que irá ser reponsável 
         * por controlar a quantidade de conexões no banco de dados, além de informar 
         * qual usuário,senha, url de conexão com o banco e o driver utilizado, 
         * driver este que implementas as interfaces da API do JDBC.
         */
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword(""); 
        dataSource.setUrl("jdbc:mysql://localhost:3306/casadocodigo?useTimezone=true&serverTimezone=UTC");
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        //dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }


    public Properties aditionalProperties() {
        /*
         * Configurações de propriedade do Hibernate, tipo de dialeto do banco de dados utilizado: 
         * Mysql, PostGress,SQLServer, Oracle ou DB2, forma de trabalho do banco de dados, 
         * update reflete cada alteração da entidade no banco de dados.
        */
        Properties props = new Properties();
        props.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        props.setProperty("hibernate.show_sql", "true");
        props.setProperty("hibernate.hbm2ddl.auto", "update");
        return props;
    }

   @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory emf){
        return new JpaTransactionManager(emf);
    }


}
public class DataSourceConfigurationTest {

    @Bean
    @Profile("test")
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("");
        dataSource.setUrl("jdbc:mysql://localhost:3306/casadocodigo_test?useTimezone=true&serverTimezone=UTC");
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");

        return dataSource;
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
classes = {JPAConfiguration.class,ProdutoDAO.class,DataSourceConfigurationTest.class,UsuarioDAO.class})
@ActiveProfiles("test")
public class ProdutoDAOTest {

    @Autowired
    public ProdutoDAO produtoDao;

    @Test
    @Transactional
    public void deveSomarTodosOsPrecosPorTipoLivro() {

        List<Produto> livrosImpressos = ProdutoBuilder.newProduto(TipoPreco.IMPRESSO, BigDecimal.TEN).more(3).buildAll();
        List<Produto> livrosEbook = ProdutoBuilder.newProduto(TipoPreco.EBOOK, BigDecimal.TEN).more(3).buildAll();

        livrosImpressos.stream().forEach(produtoDao::gravar);
        livrosEbook.stream().forEach(produtoDao::gravar);

        BigDecimal valor = produtoDao.somaPrecosPorTipo(TipoPreco.EBOOK);
        Assert.assertEquals(new BigDecimal(40).setScale(2), valor);
    }

}
3 respostas
package br.com.casadocodigo.loja.conf;

import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;


/***
 * @author shun
 * Classe de inicialização do Servlet Spring que é responsável por configurar qual será o endereço
 * monitorado e indicar quais classes são responsáveis 
 * por cuidar das configurações da aplicação.
 */
public class ServletSpringMVC extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {SecurityConfiguration.class,
        AppWebConfiguration.class, JPAConfiguration.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {};
    }

    @Override //Configura qual será a url rastreada
    protected String[] getServletMappings() {
        return new String [] {"/"};
    }


    @Override //Configura o uso do econding UTF8 no lado do servidor
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");
        return new Filter[] {encodingFilter};
    }

    /**
     * Registra o MultipartConfig
     * Configura que iremos trabalhar com arquivos de multipart
     * do tipo :texto , imagem, som ou vídeo.
     */
    @Override
    protected void customizeRegistration(Dynamic registration) {
        registration.setMultipartConfig(new MultipartConfigElement(""));
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
        servletContext.addListener(new RequestContextListener());
        servletContext.setInitParameter("spring.profiles.active", "dev");
    }
}

Depois de muito testar o que para mim funcionou foi mudar o perfil DDL do Hibernate na Classe JPAConfiguration para create e voltar para update.

Já que o perfil update não estava conseguindo criar a estrutura das tabelas.

E a partir dai funcionou tudo bem.

Troquei o Driver mysql 8 para 5 depois usei o próprio jdbc do spring. Todos deram exatamente o mesmo problema , não conseguiram criar a estrutura das tabelas no banco dados.

Curioso que Rodando a aplicação o perfil Update do DDL consegue criar toda estrutura certinha do banco, já quando usamos o perfil de teste ...

Até mesmo um pom do módulo 8 inicial eu baixei para teste.(Mesmo erro), verifiquei os imports e cheguei a inclusive limpar o repository do maven local para não ter nada em conflito.

Se alguém souber uma outra solução que não seja essa de mudar o DDL para create e depois voltar para update me avisa por gentileza

Oi João

Por alguma incompatibilidade entre versões o Hibernate não consegue criar tabelas dependendo do dialect configurado. Por exemplo, eu já tive problemas com o create-drop usando o MysqlInnoDBDialect para o MySQL5, mudando para MySQL5InnoDBDialect resolveu esse issue.