JPA não envia as informações para o banco

6 respostas
G

Boa tarde pessoal, estou criando uma aplicação que utilizará EJB, JPA, Mysql com o JBoss 7.1.1.
O que acontece é que ao realizar o persist de um objeto, o mesmo não lança nenhuma exceção mas também não grava nada no banco. Vou postar os trechos de código e configurações que acho mais importante para ver se podem me ajudar.

persistence.xml

<?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="nycstorePU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>java:jboss/datasources/MySqlDSNYCStore</jta-data-source>
    <class>br.com.nycstore.core.entities.Sale</class>
    <class>br.com.nycstore.core.entities.Email</class>
    <class>br.com.nycstore.core.entities.PaymentType</class>
    <class>br.com.nycstore.core.entities.City</class>
    <class>br.com.nycstore.core.entities.Purchase</class>
    <class>br.com.nycstore.core.entities.Grade</class>
    <class>br.com.nycstore.core.entities.Payment</class>
    <class>br.com.nycstore.core.entities.PaymentParcel</class>
    <class>br.com.nycstore.core.entities.Register</class>
    <class>br.com.nycstore.core.entities.SaleItem</class>
    <class>br.com.nycstore.core.entities.Receipt</class>
    <class>br.com.nycstore.core.entities.Address</class>
    <class>br.com.nycstore.core.entities.ReceiptType</class>
    <class>br.com.nycstore.core.entities.Groups</class>
    <class>br.com.nycstore.core.entities.ReceiptParcel</class>
    <class>br.com.nycstore.core.entities.Phone</class>
    <class>br.com.nycstore.core.entities.Product</class>
    <class>br.com.nycstore.core.entities.PurchaseItem</class>
    <class>br.com.nycstore.core.entities.States</class>
    <class>br.com.nycstore.core.entities.Login</class>
    <properties>
            <property name="jboss.as.jpa.providerModule" value="org.eclipse.persistence.jpa" />
        </properties>
  </persistence-unit>
</persistence>

datasource e driver dentro de standalone.xml (JBoss)

<datasource jta="true" jndi-name="java:jboss/datasources/MySqlDSNYCStore" pool-name="MySQLDSNYCStore" enabled="true" use-java-context="true" use-ccm="true">
                    <connection-url>jdbc:mysql://localhost:3306/NYCStore</connection-url>
                    <driver>mysql</driver>
                    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
                    <pool>
                        <prefill>true</prefill>
                        <use-strict-min>false</use-strict-min>
                        <flush-strategy>FailingConnectionOnly</flush-strategy>
                    </pool>
                    <security>
                        <security-domain>security-encrypted-NYCStore</security-domain>
                    </security>
                </datasource>
                <drivers>
                    <driver name="h2" module="com.h2database.h2">
                        <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
                    </driver>
                    <driver name="mysql" module="mysql.jdbc">
                        <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
                    </driver>
                </drivers>

Assinatura da classe de business

@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
@Stateless
public class RegisterBusinessImpl extends GenericBusiness implements RegisterBusiness {

Assinatura do método no business

@Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void save(Register register, ApplicationType applicationType) throws BusinessException, ValidateException {

Classe de persistencia

@PersistenceContext(unitName="nycstorePU")
    private EntityManager entityManager;

@Override
    public void persist(T entity) throws DAOException {
        try {
            log.debug("Start save entity " + entity);
            this.entityManager.persist(entity);
            log.debug("End save entity " + entity);
        } catch (javax.persistence.PersistenceException pe) {
            log.debug("Erro ao salvar entity = " + entity, pe);
            throw new DAOException("Erro ao salvar", pe);
        } catch (Exception e) {
            log.debug("Erro ao salvar entity = " + entity, e);
            throw new DAOException("Erro ao salvar", e);
        }
    }

Aparentemente é como se ele não estivesse trabalhando com transação, mas o mais estranho é que não lança nenhuma Exception.

Qualquer ajuda é bem vinda.

6 Respostas

rmendes08

Cara, posta o código do EJB, algum erro deve ter. De repente você tá ignorando alguma exceção que acha que não é importante.

G

Boa tarde rmendes08
segue abaixo o código do EJB. Ele é bem simples, apenas chama a camada de Business.

@Stateless(name = "EJBRegister", mappedName = "EJBRegister")
public class EJBRegister implements EJBRegisterRemote {

    @Inject
    private BusinessLocator businessLocator;
    private Logger log = Logger.getLogger(EJBRegister.class);

    @Override
    public void save(Register entity, ApplicationType applicationType) throws EJBException {
        try {
            businessLocator.getRegisterBusiness().save(entity, applicationType);
        } catch (BusinessException ex) {
            throw new EJBException(ex.getMessage(), ex.getSwingMessage(), ex);
        } catch (ValidateException ex) {
            throw new EJBException(null, ex.getMessage(), ex);
        }
    }

trecho do BusinessLocator

public class BusinessLocatorImpl implements BusinessLocator {

    @Inject
    private RegisterBusiness registerBusiness;

    @Override
    public RegisterBusiness getRegisterBusiness() {
        return registerBusiness;
    }
}

Obrigado por ajudar!

rmendes08

Cara, coloca o código completo da sua classe de persistência. Outra coisa que você pode fazer é debugar o momento da persistência e verificar no entityManager se existe alguma transação ativa.

Outra coisa, eu estou vendo que você faz o encadeamento de vários EJB’s sem necessidade. Embora os EJB’s tragam algumas facilidades (injeção do contexto de persistência, interceptors, demarcação de transiçã, etc.) isso não vem de graça, o servidor de aplicação de arcar com esse custo (pools de instâncias, interceptar chamadas, proxies). Sendo assim, nem todo objeto dentro do servidor de aplicação tem que ser um EJB (nem deve). Utilize os EJB’s apenas para expor serviços (Facade, assim fica mais fácil você demarcar suas transações.

G

Obrigado mais uma vez por tentar ajudar.

A questão de ser tudo EJB é por que já estava testando de tudo que é jeito aqui e nada...hehe na realizada o único deve ser o EJBRegister no meu caso (havia colocado no business para teste) Segue abaixo a classe que faz a persistência.
package br.com.nycstore.core.dao.impl;

import br.com.nycstore.core.dao.DAOException;
import br.com.nycstore.core.dao.GenericDAO;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import org.apache.log4j.Logger;

public abstract class JPAGenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {

    Logger log = Logger.getLogger(JPAGenericDAOImpl.class);
    @PersistenceContext(unitName="nycstorePU")
    private EntityManager entityManager;
    
    private String getSimpleName(){
        ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();  
        return ((Class)((ParameterizedType) superclass).getActualTypeArguments()[0]).getSimpleName();
    }

    @Override
    public void persist(T entity) throws DAOException {
        try {
            log.debug("Start save entity " + entity);
            this.entityManager.merge(entity);
            log.debug("End save entity " + entity);
        } catch (javax.persistence.PersistenceException pe) {
            log.debug("Erro ao salvar entity = " + entity, pe);
            throw new DAOException("Erro ao salvar", pe);
        } catch (Exception e) {
            log.debug("Erro ao salvar entity = " + entity, e);
            throw new DAOException("Erro ao salvar", e);
        }catch (Throwable e){
            log.debug("Erro ao salvar entity = " + entity, e);
            throw new DAOException("Erro ao salvar", e);
        }
    }

    @Override
    public void persist(List<T> entities) throws DAOException {
        try {
            for (T entity : entities) {
                log.debug("Start save entity " + entity);
                this.entityManager.persist(entity);
                log.debug("End save entity " + entity);
            }
        } catch (javax.persistence.PersistenceException pe) {
            log.debug("Erro ao salvar coleção de entity", pe);
            throw new DAOException("Erro ao salvar", pe);
        } catch (Exception e) {
            log.debug("Erro ao salvar coleção de entity", e);
            throw new DAOException("Erro ao salvar", e);
        }
    }

    @Override
    public T merge(T entity) throws DAOException {
        try {
            log.debug("Start merge entity " + entity);
            entity = this.entityManager.merge(entity);
            log.debug("End merge entity " + entity);
            return entity;
        } catch (javax.persistence.PersistenceException pe) {
            log.debug("Erro ao realizar merge entity = " + entity, pe);
            throw new DAOException("Erro ao salvar", pe);
        } catch (Exception e) {
            log.debug("Erro ao realizar merge entity = " + entity, e);
            throw new DAOException("Erro ao salvar", e);
        }
    }

    @Override
    public void remove(T entity) throws DAOException {
        try {
            log.debug("Start remove entity " + entity);
            this.entityManager.remove(entity);
            log.debug("End remove entity " + entity);
        } catch (javax.persistence.PersistenceException pe) {
            log.debug("Erro ao remover entity = " + entity, pe);
            throw new DAOException("Erro ao remover", pe);
        } catch (Exception e) {
            log.debug("Erro ao remover entity = " + entity, e);
            throw new DAOException("Erro ao remover", e);
        }
    }

    @Override
    public void remove(List<T> entities) throws DAOException {
        try {
            for (T entity : entities) {
                log.debug("Start remove entity " + entity);
                this.entityManager.remove(entity);
                log.debug("End remove entity " + entity);
            }
        } catch (javax.persistence.PersistenceException pe) {
            log.debug("Erro ao remover entities", pe);
            throw new DAOException("Erro ao remover entities", pe);
        } catch (Exception e) {
            log.debug("Erro ao remover entities", e);
            throw new DAOException("Erro ao remover entities", e);
        }
    }

    @Override
    public Integer count() throws DAOException {
        try {
            log.debug("Start find all entities");
            Integer count =  ((Number)this.entityManager.createNamedQuery(getSimpleName()+".count").getSingleResult()).intValue();
            log.debug("End find all entities");
            return count;
            
        } catch (javax.persistence.PersistenceException pe) {
            log.debug("Erro ao localizar entities", pe);
            throw new DAOException("Erro ao localizar", pe);
        } catch (Exception e) {
            log.debug("Erro ao localizar entities", e);
            throw new DAOException("Erro ao localizar", e);
        }
    }

    @Override
    public T find(ID id) throws DAOException {
        try {
            log.debug("Start find entity " + id);
            Object obj = this.entityManager.createNamedQuery(getSimpleName()+".findById").setParameter("id", id).getSingleResult();
            log.debug("End find entity " + obj);
            return obj != null ? (T) obj : null;
            
        } catch(NoResultException e){
            return null;
        } catch (PersistenceException pe) {
            log.debug("Erro ao localizar entity = " + id, pe);
            throw new DAOException("Erro ao localizar", pe);
        } catch (Exception e) {
            log.debug("Erro ao localizar entity = " + id, e);
            throw new DAOException("Erro ao localizar", e);
        }
    }

    @Override
    public List<T> find(List<ID> ids) throws DAOException {
        List<T> entities = new ArrayList<>();
        try {
            log.debug("Start find entity by ids " + ids);
            for(ID id : ids){
                entities.add(find(id));
            }
            log.debug("End find entity by ids " + ids);
            return entities;
            
        } catch (PersistenceException pe) {
            log.debug("Erro ao localizar entities by ids " + ids, pe);
            throw new DAOException("Erro ao localizar", pe);
        } catch (Exception e) {
            log.debug("Erro ao localizar entities by ids " + ids, e);
            throw new DAOException("Erro ao localizar", e);
        }
    }

    @Override
    public List<T> findAll() throws DAOException {
        try {
            log.debug("Start find all entities");
            List<T> list = this.entityManager.createNamedQuery(getSimpleName()+".findAll").getResultList();
            log.debug("End find all entities");
            return list;
            
        } catch (PersistenceException pe) {
            log.debug("Erro ao localizar entities", pe);
            throw new DAOException("Erro ao localizar", pe);
        } catch (Exception e) {
            log.debug("Erro ao localizar entities", e);
            throw new DAOException("Erro ao localizar", e);
        }
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }
}
G

A transação no momento da persistencia não está ativa realmente. O que poderia estar acontecendo?

rmendes08

O mais provável é que a demarcação da transação não esteja correta. Por isso que eu disse que é interessante utilizar o EJB somente como Facade.

Acho que uma outra possibilidade é o conteiner criar um EntityManager’s ao demarcar uma transação e injetar outro EntityManager no seu GenericDao.

Criado 7 de fevereiro de 2013
Ultima resposta 7 de fev. de 2013
Respostas 6
Participantes 2