Olá Pessoal tudo bem? Bom estou com um problema com o meu JPA aparentemente qualquer tentativa de salvar um objeto ele não funciona basicamente java.lang.NullPointerException
MEU DAO GENERICO:
public class GenericoDAO<T extends Entidade> {
@PersistenceUnit(unitName="MeusistemaPU")
EntityManagerFactory factory;
public EntityManager getEM() throws InstantiationException, IllegalAccessException{
return factory.createEntityManager();
}
public T salvar (T t) throws Exception{
EntityManager em = getEM();
try{
em.getTransaction().begin();
if(t.getId() == null){
em.persist(t);
}else{
if(!em.contains(t)){
if(em.find(t.getClass(),t.getId()) == null){
throw new Exception("Erro ao atualizar");
}
}
t = em.merge(t);
}
em.getTransaction().commit();
}finally{
em.close();
}
return t;
}
}
Minha Interface Entidade:
public interface Entidade {
public Integer getId();
}
Minha Classe de Teste
public class AnimalTeste {
public static void main(String[] args) throws Exception {
Animal gato = new Animal();
GenericoDAO gn = new GenericoDAO();
gato.setDataNascimento("12-02-2013");
gato.setNomeAnimal("Felix");
gato.setPelagem("Preta");
gato.setPeso(4.35);
System.out.println(gato.toString());
//Neste momento no gn.salvar ele nem entra e já lança a Exception
gn.salvar(gato);
}
}
Meu Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="MeusistemaPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.entidade.Animal</class>
<properties>
<property name="eclipselink.jdbc.batch-writing" value="JDBC" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/animais" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="1234" />
<property name="eclipselink.target-database" value="MySQL"/>
</properties>
</persistence-unit>
</persistence>
Aqui o Erro que da
Exception in thread "main" java.lang.NullPointerException
at com.DAO.GenericoDAO.getEM(GenericoDAO.java:16)
at com.DAO.GenericoDAO.salvar(GenericoDAO.java:20)
at com.teste.AnimalTeste.main(AnimalTeste.java:28)
Pelo o que pude ver acredito que seu código não está conseguindo recuperar a instância do objeto no momento em que você faz getEM();
bem no trecho abaixo:
public T salvar (T t) throws Exception{
EntityManager em = getEM(); //Ponto em que a instância não foi recuperada
Faça um debug no código pra ver por que não está recuperando.
Remove o :
em.getTransaction().commit();
E tenta salvar agora…
Eu removi, porem mesmo com o em.getTransaction… Meu AnimalTeste(main) não chega nem a chamar o metodo salvar da classe GenericoDAO
O Debug ele termina em:
public EntityManager getEM() throws InstantiationException, IllegalAccessException{
return factory.createEntityManager(); //Neste trecho está Null
}
Fiz um teste no meu GenericoDAO comentando tudo e deixando apenas um toString no metodo Salvar o Objeto está sendo passado normalmente
Tenta criar a fabrica manualmente e veja o que acontece!
private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("MeusistemaPU");
ps: arranca ela do GenericDao
e coloca em uma JpaUtil
, por exemplo.
ps2: acho interessante que tenha vários DAO’s que estendam GenericDao, passando a classe no diamond
1 curtida
O Erro agora é:
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.teste.AnimalTeste.main(AnimalTeste.java:12)
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named MeusistemaPU
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:84)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
Acredito que seu erro foi criado por falta de atenção com o nome da sua unidade de persistência.
Seu projeto tem um arquivo de configuração chamado persistence.xml, nele você encontrará o nome da sua unidade de persistência. A linha do arquivo é essa:
`<persistence-unit name="AppJSFPU" transaction-type="RESOURCE_LOCAL">`
Por padrão o nome criado automaticamente é o nome do seu projeto no exemplo acima AppJSF + PU de Persistence Unit.
Recomendo além do DAO genérico, você implementar uma classe para criar o EntityManager. Crie esta classe no pacote DAO assim (é uma classe Java normal só por desencargo de consciência kkkkkk):
public class PersistenceUtil {
private static EntityManagerFactory emf = null;
private PersistenceUtil() {
}
public static EntityManager getEntityManager() {
if (emf == null) {
emf = Persistence.createEntityManagerFactory("AppJSFPU");
}
return emf.createEntityManager();
}
public static void close(EntityManager em) {
if (em != null) {
em.close();
}
}
}
Seu DAO genérico pode ficar assim:
public class DaoGenerico implements Serializable {
private static DaoGenerico instance = new DaoGenerico();
private EntityManagerFactory emf = null;
public static DaoGenerico getInstance() {
return instance;
}
private DaoGenerico() {
}
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public void save(Object objeto) {
EntityManager em = null;
try {
em = PersistenceUtil.getEntityManager();
em.getTransaction().begin();
em.persist(objeto);
em.getTransaction().commit();
} catch (Exception ex) {
} finally {
if (em != null) {
em.close();
}
}
}
public void update(Object objetoAtualizado) {
EntityManager em = null;
try {
em = PersistenceUtil.getEntityManager();
em.getTransaction().begin();
em.merge(objetoAtualizado);
em.getTransaction().commit();
} catch (Exception ex) {
System.out.println("Erro:" + ex.getMessage());
} finally {
if (em != null) {
em.close();
}
}
}
public void delete(Object objeto) {
EntityManager em = null;
try {
em = PersistenceUtil.getEntityManager();
em.getTransaction().begin();
Object objetoDeletar = em.merge(objeto);
em.remove(objetoDeletar);
em.getTransaction().commit();
} catch (Exception ex) {
} finally {
if (em != null) {
em.close();
}
}
}
}
Notas:
-
O DAO genérico acima esta chamando o método getEntityManager da classe PersistenceUtil, caso você queira continuar usando a sua classe DAO acrescente a chamada a esse método lá.
-
Não se esqueça de trocar o nome da unidade de persistência na classe PersistenceUtil.
emf = Persistence.createEntityManagerFactory(“AppJSFPU”);
-
A classe PersistenceUtil e o DAO genérico do exemplo utilizam um padrão de projeto chamado singleton, caso queira dar uma lida para saber mais recomendo:
Devmedia-Trabalhando com singleton
Problema Resolvido, troquei a versão do Jar do Hibernate para a 4.2.8 funcionou perfeitamente.