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

Dúvida no Ex. 7 da Aula 2 - Configuração e inicialização do JPA

Boa tarde.

Estou fazendo o exercicio em um servidor JBoss EAP 6.4. Criei a entidade Conta devidamente anotada, criei a persistence unit com as informações do banco. Ao iniciar o JBoss, a persistence unit inicia sem problemas. Estou tendo problemas na hora de executar o client (TesteJPA).

Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: financas] Unable to build EntityManagerFactory

Caused by: org.hibernate.service.jndi.JndiException: Error parsing JNDI name [java:jboss/datasources/financas]

Pelo que investiguei até agora, o jndi name não é visto fora do container. O client TesteJPA é executado como uma aplicação Java e não está dentro da JVM.

Como fazer para que o exercicio funcione, diante do exposto acima?

Obrigado.

16 respostas

Oi Angelo,

Dentro de um servidor de aplicação você precisa de um datasource configurado. Além disso, você não pode mais executar o JPA a partir de "main" já que o servidor é responsável por levantar o JPA/Conexão.

Tudo isso tem a ver com EJB. Aconselho dar uma olhada no treinamento sobre EJB no Alura:

https://www.alura.com.br/course/ejb

Abs

Oi Angelo,

Coloca aqui o código do seu TesteJPA, assim terei ideia do que você está tentando fazer.

Abraço

Paulo, boa tarde. Obrigado pela ajuda. Segue o código.

package br.com.caelum.financas.test;

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

import br.com.caelum.financas.model.Conta;

public class TesteJPA {

    public static void main(String[] args) {

        Conta conta = new Conta();
        conta.setTitular("Thiago Reis");
        conta.setBanco("Banco do Brasil");
        conta.setAgencia("1581-9");
        conta.setNumero("14820-9");
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("financas");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        em.persist(conta);
        em.getTransaction().commit();
        em.close();



    }

}

Abaixo, a exceção lançada.

xception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: financas] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:925)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:900)
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:59)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
    at br.com.caelum.financas.test.TesteJPA.main(TesteJPA.java:18)
Caused by: org.hibernate.service.jndi.JndiException: Error parsing JNDI name [java:jboss/datasources/financas]
    at org.hibernate.service.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:92)
    at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:63)
    at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:116)
    at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:85)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:184)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:156)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:223)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:89)
    at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:85)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:184)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:156)
    at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1827)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1785)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915)
    ... 5 more
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:344)
    at javax.naming.InitialContext.getNameParser(InitialContext.java:499)
    at org.hibernate.service.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:86)
    ... 19 more

Nico, boa tarde.

Obrigado pela ajuda mas não possuo acesso (ainda) ao módulo de EJB.

Angelo, seu problema deve estar no persistence.xml. Coloca aqui como está seu arquivo também.

O código Java parece estar certinho.

Abraço

Paulo, segue.

desculpe, mas qualquer código que posto aqui perde a identação.

<?xml version="1.0" encoding="UTF-8"?>

org.hibernate.ejb.HibernatePersistence java:jboss/datasources/financas br.com.caelum.financas.model.Conta

<?xml version="1.0" encoding="UTF-8"?>

org.hibernate.ejb.HibernatePersistence java:jboss/datasources/financas br.com.caelum.financas.model.Conta

Não estou conseguindo postar o persistence.xml. Parece que está truncando. Pelos logs do JBoss, a PU está subindo corretamente, inclusive criando a tabela no banco.

4:56:56,003 INFO [org.hibernate.ejb.Ejb3Configuration] (ServerService Thread Pool -- 50) HHH000204: Processing PersistenceUnitInfo [ name: financas ...]

4:56:57,425 INFO [stdout] (ServerService Thread Pool -- 50) Hibernate: 14:56:57,425 INFO [stdout] (ServerService Thread Pool -- 50) drop table if exists CONTA cascade

14:56:57,452 INFO [stdout] (ServerService Thread Pool -- 50) Hibernate: 14:56:57,452 INFO [stdout] (ServerService Thread Pool -- 50) drop sequence hibernate_sequence

14:56:57,455 INFO [stdout] (ServerService Thread Pool -- 50) Hibernate: 14:56:57,455 INFO [stdout] (ServerService Thread Pool -- 50) create table CONTA ( 14:56:57,455 INFO [stdout] (ServerService Thread Pool -- 50) id int4 not null, 14:56:57,455 INFO [stdout] (ServerService Thread Pool -- 50) agencia varchar(255), 14:56:57,455 INFO [stdout] (ServerService Thread Pool -- 50) banco varchar(255), 14:56:57,455 INFO [stdout] (ServerService Thread Pool -- 50) numero varchar(255), 14:56:57,456 INFO [stdout] (ServerService Thread Pool -- 50) titular varchar(255), 14:56:57,456 INFO [stdout] (ServerService Thread Pool -- 50) primary key (id) 14:56:57,456 INFO [stdout] (ServerService Thread Pool -- 50) )

14:56:57,569 INFO [stdout] (ServerService Thread Pool -- 50) Hibernate: 14:56:57,570 INFO [stdout] (ServerService Thread Pool -- 50) create sequence hibernate_sequence start 1 increment 1

14:56:57,572 INFO [org.hibernate.tool.hbm2ddl.SchemaExport] (ServerService Thread Pool -- 50) HHH000230: Schema export complete 14:56:57,597 INFO [org.jboss.web] (ServerService Thread Pool -- 128) JBAS018210: Registra o contexto da web: /financas

Angelo, coloque o código do persistence dentro de 3 crases, seguindo as dicas de formatação que tem no forum. Assim o fórum permite.

Assim: ``` E depois, ao terminar o código mais 3 para fechar.

```<?xml version="1.0" encoding="UTF-8"?>

org.hibernate.ejb.HibernatePersistence java:jboss/datasources/financas br.com.caelum.financas.model.Conta ```

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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">
    <persistence-unit name="financas" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:jboss/datasources/financas</jta-data-source>
        <class>br.com.caelum.financas.model.Conta</class>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="create"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
            <property name="hibernate.format_sql" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

Aqui o datasource configurado.

                <datasource jta="true" jndi-name="java:jboss/datasources/financas" pool-name="financasDS" enabled="true" use-ccm="true" statistics-enabled="false">
                    <connection-url>jdbc:postgresql://10.0.37.87:5432/financas</connection-url>
                    <driver-class>org.postgresql.Driver</driver-class>
                    <driver>postgresql-9.4-1201.jdbc4.jar</driver>
                    <pool>
                        <min-pool-size>1</min-pool-size>
                        <max-pool-size>5</max-pool-size>
                    </pool>
                    <security>
                        <user-name>restricted</user-name>
                        <password>restricted</password>
                    </security>
                    <validation>
                        <validate-on-match>false</validate-on-match>
                        <background-validation>false</background-validation>
                    </validation>
                    <timeout>
                        <set-tx-query-timeout>false</set-tx-query-timeout>
                        <blocking-timeout-millis>0</blocking-timeout-millis>
                        <idle-timeout-minutes>0</idle-timeout-minutes>
                        <query-timeout>0</query-timeout>
                        <use-try-lock>0</use-try-lock>
                        <allocation-retry>0</allocation-retry>
                        <allocation-retry-wait-millis>0</allocation-retry-wait-millis>
                    </timeout>
                    <statement>
                        <share-prepared-statements>false</share-prepared-statements>
                    </statement>
                </datasource>

Oi Angelo,

na minha opinião o seu persistence.xml só vai funcionar se vc usa uma aplicação que roda dentro do JBoss (por exemplo, uma webapp publicado no JBoss).

Usando o main vc está criando uma nova JVM fora do JBoss que não tem acesso ao contexto JNDI do JBoss.

Tudo bem?

abs

solução!

Entendi agora. Angelo, você está usando um persistence que foi criado para rodar no servidor, porém esse seu código é standalone.

Você precisa usar seu persistence.xml assim:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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">
    <persistence-unit name="financas">

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

        <class>br.com.caelum.financas.model.Conta</class>

        <properties>

        <!-- Propriedades JDBC -->
        <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
        <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/fj25" />
        <property name="javax.persistence.jdbc.user" value="restricted" />
        <property name="javax.persistence.jdbc.password" value="restricted" />

        <!-- Configuracoes especificas do Hibernate -->
        <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
                <!-- Usamos update para atualizar sempre o banco de acordo com nosso modelo -->
        <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>

Veja se assim resolve. Usando DataSource, você precisa estar em um servidor de aplicação ou usar um embedded. Apenas rodar no java na mão não irá funcionar.

Abraço

Exatamente como Nico falou acima, por isso você precisa de um persistence.xml como coloquei na resposta anterior.

Abraço

Perfeito Paulo.

Realmente não me atentei que estava tentando utilizar um recurso que era gerenciado pelo servidor através de uma aplicação standalone.

Funcionou.

Muito obrigado pela ajuda.

um abraço.

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