Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Erro ao executar TestaConta (Maven / MySQL)

Pessoal, sou novato no Maven, portanto decidi realizar todos os cursos utilizando ele pra ver se pego o jeito.

Dito isto, apesar de ele ajudar bastante na importação e manutenção de bibliotecas, ele cria estruturas de projeto as vezes bem diferente das dos cursos e no caso deste, pode ser que meu problema esteja aí (não sei. Quero ver com vocês). O Maven cria dois caminhos de pacote. Um com as classes do sistema e uma para teste.

  • Caso a classe TestaConta for criada no caminho de teste (apesar do nome de pacote ser igual), ele dá o seguinte erro:

"Erro: Não foi possível localizar nem carregar a classe principal br.com.dominioficticio.finances.AccountTest"

  • Caso a classe TestaConta for criada no caminho normal de desenvolvimento, estoura a seguinte exception:
Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named finances-mysql
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at br.com.dominioficticio.finances.AccountTest.main(AccountTest.java:19)

Porém, o arquivo persistence.xml existe e está em uma pasta META-INF no src. Segue abaixo como ela está descrita:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">

    <persistence-unit name="finances-mysql">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>br.com.dominioficticio.finances.model.Account</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/finances" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />

            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
        </properties>
    </persistence-unit>

</persistence>

O banco de dados MySQL "finances" existe e está em branco (havia utilizado ele na versão anterior do curso sem o Maven e havia funcionado. Agora limpei ele para usar no novo curso)

Segue abaixo minha classe TestaConta:

package br.com.dominioficticio.finances;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import br.com.dominioficticio.finances.model.Account;

public class AccountTest {

    public static void main(String[] args) {

        Account account = new Account();
        account.setHolder("Holder's name");
        account.setOffice("0123");
        account.setBank("Bank's name");
        account.setNumber("0123456789");

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("finances-mysql");
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();
        em.persist(account);
        em.getTransaction().commit();

        em.close();
        emf.close();

    }
}

Segue abaixo meu pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>br.com.dominioficticio</groupId>
    <artifactId>finances</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>finances</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>
    </dependencies>
</project>

O que posso estar fazendo errado?

Obrigado!

6 respostas

Eis o meu chute:

<provider>org.hibernate.ejb.HibernatePersistence</provider>

apaga essa linha.

Alberto, não funcionou. Mas não achei que fosse funcionar também, porque ele está dizendo que não encontra o provider. Remover justamente esta linha não deve resolver o problema.

Tenho uma desconfiança que talvez ele não esteja encontrando o arquivo persistence.xml. Como o projeto sabe onde este arquivo fica? Talvez eu esteja esquecendo de passar o caminho dele em algum lugar...

Ou talvez por estar usando o Maven eu deveria estar rodando o projeto pelo maven? O curso de Maven explica como fazer isso com um sistema web, mas não sei como rodar um aplicativo como este...

Aquela linha do provider estava apontando para um provider deprecated, não deveria estar ali mesmo. O arquivo fica pasta META-INF dentro do src/main/resources (mais comum) ou src/main/java. Isso é definido pela especificação, você não precisa passar em lugar nenhum.

Sobre a linha do provider, está escrito exatamente como é dado no curso. Precisaria então atualizar o curso mais uma vez.

Sobre a pasta META-INF, o instrutor diz que deve ser criada diretamente na pasta src, que é exatamente o que ele faz no vídeo e também o que fiz. Se isto também mudou, mais um motivo pra atualizar o curso novamente.

Assim que estiver em casa, testarei a tua sugestão.

Obrigado!

Continua não funcionando... Mas teve evolução. Por "evolução", lê-se ocorreram erros novos, mas parece que agora estou indo no caminho certo hehehe

Mais adiante na parte escrita desta aula, é apresentada uma dependência a ser utilizada no Maven que é diferente da que eu encontrei quando pesquisei por conta.

  • Troquei a dependência no pom.xml
  • Coloquei o persistence.xml em src/main/resources/META-INF e testei. Continuou dando o mesmo erro.
  • Coloquei a pasta META-INF de volta direto na pasta src e deu erro dizendo que não encontrou um persistence.xml. Aí vi que estava indo no caminho certo. Coloquei de volta em src/main/resources
  • removi a tag com ohavias sugerido inicialmente e agora o erro é este (Parece que ele finalmente conectou no banco, mas tá pauleando no timezone do MySQL):
Exception in thread "main" org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:271)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:233)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:242)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:858)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:885)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at br.com.bergamin.finances.AccountTest.main(AccountTest.java:19)
Caused by: org.hibernate.exception.JDBCConnectionException: Error calling Driver#connect
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator$1$1.convert(BasicConnectionCreator.java:105)
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:123)
    at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:41)
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:58)
    at org.hibernate.engine.jdbc.connections.internal.PooledConnections.addConnections(PooledConnections.java:123)
    at org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init>(PooledConnections.java:42)
    at org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init>(PooledConnections.java:20)
    at org.hibernate.engine.jdbc.connections.internal.PooledConnections$Builder.build(PooledConnections.java:161)
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildPool(DriverManagerConnectionProviderImpl.java:109)
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:72)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:242)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:259)
    ... 14 more
Caused by: java.sql.SQLException: The server time zone value 'Hora oficial do Brasil' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:545)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:513)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:505)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:479)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:489)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:69)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:1606)
    at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:633)
    at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:347)
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:219)
    at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:38)
    ... 29 more
Caused by: com.mysql.cj.core.exceptions.InvalidConnectionAttributeException: The server time zone value 'Hora oficial do Brasil' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at com.mysql.cj.core.exceptions.ExceptionFactory.createException(ExceptionFactory.java:54)
    at com.mysql.cj.core.exceptions.ExceptionFactory.createException(ExceptionFactory.java:73)
    at com.mysql.cj.jdbc.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:118)
    at com.mysql.cj.mysqla.MysqlaSession.configureTimezone(MysqlaSession.java:293)
    at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:2399)
    at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:1739)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:1596)
    ... 33 more

Estou fuçando nas configurações no MySQL Workbench, mas se alguém souber como resolver este problema rapidamente, agradeço de antemão

solução!

Cara, que briga... Mas finalmente consegui fazer essa coisa funcionar. Como a solução ficou espalhada em mais de uma resposta, vou adicionar aqui tudo o que corrigiu o problema:

  • Arquivo persistence.xml do curso possui dados deprecated. Remover tag <provider>
  • Arquivo persistence.xml do curso é criado em local diferente da especificação atual. Criar dentro do diretório src/main/resources/META-INF
  • Estava utilizando a dependência errada. Mais adiante na parte escrita do curso, manda usar a seguinte dependência:
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>5.2.8.Final</version>
    </dependency>
  • Porém ao procurar no Maven Repository, descubro que esta dependência também está deprecated e que deve-se usar na verdade a seguinte dependência:
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.10.Final</version>
    </dependency>

Estes passos acima resolvem o problema inicial. Para resolver o problema de configuração de timezone do MySQL foi mais simples. Deve-se simplesmente rodar a seguinte linha de código no banco de dados (Substituir valor conforme o fuso):

SET GLOBAL time_zone = '-03:00';

Acredito que isto pode ainda acarretar em problemas quando for horário de verão, mas não vou me preocupar com isso agora.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software