Boa tarde galera, sou novo na programação Java. Estou estudando um projeto JPA e ao executar o projeto dá o erro: Cannot invoke “javax.persistence.EntityManagerFactory.createEntityManager()” because “infra.Aula343_DAO.emf” is null
o meu persistence.xml está da seguinte forma:
<?xml version="1.0" encoding="UTF-8"?>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>modelo.basico.Aula334_Usuario</class>
<class>modelo.basico.Aula342_Produto</class>
<class>modelo.umpraum.Aula347_Assento</class>
<class>modelo.umpraum.Aula347_Cliente</class>
<class>modelo.umpramuitos.Aula352_Pedido</class>
<class>modelo.umpramuitos.Aula352_PedidoItem</class>
<class>modelo.muitospramuitos.Aula353_Tio</class>
<class>modelo.muitospramuitos.Aula353_Sobrinho</class>
<class>modelo.muitospramuitos.Aula354_Filme</class>
<class>modelo.muitospramuitos.Aula354_Ator</class>
<properties>
<!-- pacote: com.mysql.cj.jdbc === classe: Driver -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/curso_java"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="estudo"/>
<!-- pacote: org.hibernate.dialect === classe: MySQL57Dialect -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL57Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/> <!-- se vai gerar um eskema de banco de dados
a partir das tabelas, ele vai olhar o mapeamento dos objetos e criar as tabelas
em projetos reais isso não é usado, podendo para isso o valor ser apenas NONE ou nem informar essa propriedade -->
</properties>
</persistence-unit>
a minha classe DAO está da seguinte forma:
package infra;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
//utilizando GENERICS ==>
public class Aula343_DAO {
/* por ser um ATRIBUTO estático STATIC, o entitymanagerfactor EMF deve ser inicializado na sua criação
* como está na linha abaixo
* private static EntityManagerFactory emf = Persistence.createEntityManagerFactory(“Secao16_JavaPersistenceAPI_Maven”);
* ou criado um bloco estático, que é chamado apenas na inicialização da classe
* como está feito nas linhas abaixo
* OBSERVAÇÃO, o bloco ESTÁTICO serve para todos os ATRIBUTOS ESTÁTICOS que a classe possa a ter
* por isso não tem nome, apenas STATITC {} */
private static EntityManagerFactory emf;
private EntityManager em;
private Class classe;
static {
try {
emf = Persistence.createEntityManagerFactory("Secao16_JavaPersistenceAPI");
} catch (Exception e) {
/* logar usando => log4j
* por ser uma rotina de acesso ao banco de dados, o instrutor indica a utilização do LOG4J
* para criar LOGS na inicialização */
}
}
public Aula343_DAO () {
this(null);
}
public Aula343_DAO (Class<E> classe) {
this.classe = classe;
em = emf.createEntityManager();
};
//início dos métodos que retornam a própria classe
public Aula343_DAO<E> abrirTransacao(){
em.getTransaction().begin();
return this;
}
public Aula343_DAO<E> fecharTransacao(){
em.getTransaction().commit();
return this;
}
public Aula343_DAO<E> incluir(E entidade) {
em.persist(entidade);
return this;
}
public Aula343_DAO<E> incluirAtomico(E entidade) {
/* ATÔMICO é quando no método havera os comandos que iniciam e fecham uma transação
* isso é usado quando em um método haverá mais de uma INCLUSÃO/EDIÇÃO/EXCLUSÃO e todos os EVENTOS/ACONTECIMENTOS
* devem estar dentro da mesma transação */
//aqui está a forma como o instrutor fez
return this.abrirTransacao().incluir(entidade).fecharTransacao();
//aqui está como eu fiz
//em.getTransaction().begin();
//em.persist(entidade);
//em.getTransaction().commit();
//return this;
}
//fim dos métodos que retornam a própria clase
public E obterPorID(Object ID) {
return em.find(classe, ID);
}
public List<E> obterTodos(){
return this.obterTodos(0,0);
}
public List<E> obterTodos(int qtde, int deslocamento){
if (classe == null) {
throw new UnsupportedOperationException("Classe nula");
}
//jpql => java persistence query linguage
String jpql = "select e from " + classe.getName() + " e";
TypedQuery<E> query = em.createQuery(jpql, classe);
//PAGINAÇÃO
//quantos registros deseja retornar na consulta
if (qtde > 0) {
query.setMaxResults(qtde);
}
/* o deslocamento indica onde irá iniciar a consulta ou resultado da consulta
* ex: se indicar 10 significa que o resultado retornada do 10º registro encontrado */
if (deslocamento > 0) {
query.setFirstResult(deslocamento);
}
return query.getResultList();
}
public void fechar() {
/* aqui estou fechando apenas o ENTITYMANAGER porque o ENTITYMANAGERFACTORY é STATICO, será criado apenas
* uma única vez*/
em.close();
}
}
a classe que chama a classe DAO através de GENERICS
package teste.muitospramuitos;
import infra.Aula343_DAO;
import modelo.muitospramuitos.Aula353_Sobrinho;
import modelo.muitospramuitos.Aula353_Tio;
public class Aula353_NovoTioSobrinho {
public static void main(String[] args) {
Aula353_Tio tia = new Aula353_Tio(“Maria”);
Aula353_Tio tio = new Aula353_Tio(“João”);
Aula353_Sobrinho sobrinho = new Aula353_Sobrinho(“Junior”);
Aula353_Sobrinho sobrinha = new Aula353_Sobrinho(“Ana”);
/* para haver uma relação BI-DIRECIONAL — MUITOS PARA MUITOS deve haver uma consistência nos dados
* por assim dizer
* por isso que se linkar um tio a um sobrinho, deve haver também a ligação entre o sobrinho e este tio */
tia.getSobrinhos().add(sobrinho);
sobrinho.getTios().add(tia);
tia.getSobrinhos().add(sobrinha);
sobrinha.getTios().add(tia);
tio.getSobrinhos().add(sobrinho);
sobrinho.getTios().add(tio);
tio.getSobrinhos().add(sobrinha);
sobrinha.getTios().add(tio);
Aula343_DAO<Object> dao = new Aula343_DAO<>();
dao.abrirTransacao().incluir(tia).incluir(tio).incluir(sobrinho).incluir(sobrinha).fecharTransacao();
dao.fechar();
}
}