Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
16
respostas

Dúvida auto update schema

Olá pessoal eu estava realizando o exercício opcional do primeiro capitulo do curso de JPA e no exercício era para o meu banco contas ter sido atualizado o schema dele após a execução do meu código, adicionando o campo saldo assim como adicionado na entidade no java. Porém, não foi atualizado e tive que fazer um alter table na mão lá no banco. Eu peguei o projeto original que baixei no link disponibilizado, esqueci de algo?

Só para constar, estou usando o postegres.

16 respostas

Olá você lembrou de descomentar essa linhas ?

 EntityManagerFactory emf = Persistence
        .createEntityManagerFactory("contas-postgres");

e comentar essas linhas?

EntityManagerFactory emf = Persistence
                .createEntityManagerFactory("contas-mysql");

Sim, ele esta criando o entity manager com o persistence unit do postgres corretamente. Eu fiz um teste fazendo com que fosse criado a tabela pelo hibernate e ele cria, mas alterar (update table) no caso de adicionar um campo na tabela ele não faz.

Você poderia postar seu persistence.xml e sua classe conta?

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("financas");

        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        em.persist(conta);

        em.getTransaction().commit();
        em.close();
    <persistence-unit name="contas-postgres">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>br.com.caelum.financas.modelo.Conta</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost/contas" />
            <property name="javax.persistence.jdbc.user" value="rafaelpbaptista" />
            <property name="javax.persistence.jdbc.password" value="" />

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

Nesse trecho de código

  EntityManagerFactory emf = Persistence.createEntityManagerFactory("financas")

O que está entre aspas se refere a essa linha do XML

<persistence-unit name="contas-postgres">

Então o correto seria: 1ª Opção: mudar o Java

 EntityManagerFactory emf = Persistence.createEntityManagerFactory("contas-postgres")

2ª Opção: mudar o XML

<persistence-unit name="financas">

Note que se as propriedades diferem, como o seu código, quando executamos o programa ocorre uma execeção:

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named financas

Espero ter ajudado, se está foi a solução não esqueça de marcar essa resposta como solução

ah não mandei errado o xml, no meu é como vc fala na segunda opção.

Ainda assim, não funciona.

O banco que você criou no postgres como se chama?

Banco contas

Você poderia mandar o que sai no terminal quando você executa o programa

Carlos, infelizmente agora não tenho acesso ao código, mas ele dá erro que a coluna "x" não existe na minha relação. Um erro do banco, driver postegres.

Quando tiver acesso, por favor poste pois me ajudara a identificar o erro

Carlos, finalmente tive um tempo para estudar.. ta corrida a vida e quando tem tempo da temporal na cidade... :/

bom, segue a pilha de erro.

Could not complete schema update
java.lang.NullPointerException
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(DatabaseMetadata.java:129)
    at org.hibernate.cfg.Configuration.generateSchemaUpdateScript(Configuration.java:1133)
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:212)
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:178)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:503)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1750)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:890)
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
    at br.com.caelum.financas.jpa.TesteJPA.main(TesteJPA.java:34)

Hibernate: 
    select
        nextval ('SEQ_CONTAS')
Hibernate: 
    insert 
    into
        Conta
        (agencia, banco, debitos, numero, saldo, titular, id) 
    values
        (?, ?, ?, ?, ?, ?, ?)
jul 14, 2016 8:44:07 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 0, SQLState: 42703
jul 14, 2016 8:44:07 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ERROR: column "debitos" of relation "conta" does not exist
  Posição: 36
Exception in thread "main" javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:92)
    at br.com.caelum.financas.jpa.TesteJPA.main(TesteJPA.java:47)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: ERROR: column "debitos" of relation "conta" does not exist
  Posição: 36
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80)
    ... 1 more
Caused by: org.hibernate.exception.SQLGrammarException: ERROR: column "debitos" of relation "conta" does not exist
  Posição: 36
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:122)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at com.sun.proxy.$Proxy8.executeUpdate(Unknown Source)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3028)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3469)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75)
    ... 1 more
Caused by: org.postgresql.util.PSQLException: ERROR: column "debitos" of relation "conta" does not exist
  Posição: 36
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:363)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    ... 17 more

Oi Mateus, parece que ta dando alguma coisa errada quando o hibernate vai atualizar os campos da sua tabela para adicionar a coluna debitos. Ele está reclamando justamente da falta desta coluna... Talvez no log tenha alguma informação, até pq falha de atualização de schema não gera erro no hibernate :(.

Outro jeito simples é vc adicionar a coluna diretamente na tabela :).

Alberto, é justamente o que estou fazendo, adicionando no banco via SQL. Porém queria saber o porquê não está funcionando o auto update do hibernate.

Oi Mateus, logo antes da exception tem uma mensagem assim no log: "Could not complete schema update"

Vê o que tem antes dela, desconfio que ali tenha algum indicativo do motivo da não atualização do schema.

solução!

Não utilize org.hibernate.dialect.PostgreSQLDialect. Segundo o javadoc do Hibernate este dialeto está deprecated. Utilizo org.hibernate.dialect.PostgreSQL82Dialect e não tenho mais problemas (é... já passei por esse mesmo problema por aqui).

Trecho do persistence.xml:

<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />