title: JPA and generics, why my class doesn't work?
body: <p>In my Spring web app I'm using a generic dao class:</p>
  
  <pre><code>public abstract class GenericDaoImpl&lt;T&gt; implements GenericDao&lt;T&gt; {
  
      @Override
      public T create(final T t) {
          this.getEntityManager().persist(t);
          return t;
      }
  
      @Override
      public void delete(final Object id) {
          this.getEntityManager().remove(
                  this.getEntityManager().getReference(getEntityType(), id));
      }
  
      @Override
      public T find(final Object id) {
          return (T) this.getEntityManager().find(getEntityType(), id);
      }
  
      @Override
      public T update(final T t) {
          return this.getEntityManager().merge(t);
      }
  }
  </code></pre>
  
  <p>I implement this class for every entity in my model and it works perfectly. For example:</p>
  
  <pre><code>@Repository
  public class GruppoDaoImpl extends GenericDaoImpl&lt;Gruppo&gt; implements GruppoDao {
  
  }
  </code></pre>
  
  <p>I use these dao classes in my service layer. I have a service layer for every entity in my model, but methods for most of these classes, are the same, so I tried to create a generic service class that I can extend in the same way I do for the generic dao:</p>
  
  <pre><code>public abstract class GenericAdminServiceImpl&lt;ENTITY extends AbstractEntity, DTO extends AbstractDto&gt;
      implements GenericAdminService&lt;ENTITY, DTO&gt; {
  
      private GenericDao&lt;ENTITY&gt; dao;
      private Class&lt;ENTITY&gt; entityClass;
      private Class&lt;DTO&gt; dtoClass;
  
      @SuppressWarnings({ "unchecked", "rawtypes" })
      protected GenericAdminServiceImpl(GenericDao&lt;ENTITY&gt; dao) {
          this.dao = dao;
          //
          Type t = getClass().getGenericSuperclass();
          ParameterizedType pt = (ParameterizedType) t;
          this.entityClass = (Class) pt.getActualTypeArguments()[0];
          this.dtoClass = (Class) pt.getActualTypeArguments()[1];
      }
  
      public DTO getById(Object id) {
          DTO dto = null;
          ENTITY entity = dao.find(id);
          if (entity != null) {
              try {
                  dto = dtoClass.newInstance();
                  initDto(entity, dto);
              } catch (Exception e) {
              }
          }
          return dto;
      }
  
      public void create(DTO dto) throws ServiceOperationException {
          ENTITY entity;
          try {
              entity = entityClass.newInstance();
              initEntity(dto, entity);
              Date dt = new Date();
              entity.setDataUltimoAggiornamento(dt);
              entity.setUtenteUltimoAggiornamento(dto.getLoggedUser());
              entity.setDataInserimento(dt);
              entity.setUtenteInserimento(dto.getLoggedUser());
              dao.create(entity);
          } catch (Exception e) {
              throw new ServiceOperationException("impossibile creare entity ["
                      + entityClass.getSimpleName() + "]", e);
          }
      }
  
      public void update(DTO dto) throws ServiceOperationException {
          ENTITY entity = dao.find(dto.getId());
          if (!entityExists(entity)) {
              throw new ServiceOperationException("entity non esistente ["
                      + entityClass.getSimpleName() + "#" + dto.getId() + "]");
          }
          initEntity(dto, entity);
          Date dt = new Date();
          entity.setDataUltimoAggiornamento(dt);
          entity.setUtenteUltimoAggiornamento(dto.getLoggedUser());
          dao.update(entity);
      }
  
      public void delete(Object id) throws ServiceOperationException {
          try {
              dao.delete((int) id);
          } catch (Exception e) {
              throw new ServiceOperationException(
                      "impossibile eliminare entity ["
                              + entityClass.getSimpleName() + "#" + id + "]", e); // TODO
          }
      }
  
      protected abstract void initDto(ENTITY entity, DTO outDto);
  
      protected abstract void initEntity(DTO dto, ENTITY outEntity);
  
      protected abstract boolean entityExists(ENTITY entity);
  
  }
  </code></pre>
  
  <p>Extending this class I just have to implement specific parts for every entity, leaving all the common stuff in the abstract/generic class.
  The problem is that using the generic service, <strong>merge, persist and delete don't work</strong>. Only select seems to work and I cannot understand why...</p>
  
  <p>When I run debug mode in Eclipse all seems correct. A consistent entity is passed to merge/persist methods, so why they don't work? can you help me?</p>
  
  <p><strong>UPDATE #1</strong></p>
  
  <p>This is an example of implementation:</p>
  
  <pre><code>@Service
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public class GruppoServiceImplG extends
          GenericAdminServiceImpl&lt;Gruppo, GruppoDto&gt; implements GruppoServiceG {
  
      @Autowired
      protected GruppoServiceImplG(GruppoDao gruppoDao) {
          super(gruppoDao);
      }
  
      @Override
      protected void initDto(Gruppo entity, GruppoDto outDto) {
          outDto.setId(entity.getId());
          outDto.setNome(entity.getNome());
          outDto.setDescrizione(entity.getDescrizione());
          outDto.setDataInizioValidita(entity.getDataInizioValidita());
          outDto.setDataFineValidita(entity.getDataFineValidita());
      }
  
      @Override
      protected void initEntity(GruppoDto dto, Gruppo outEntity) {
          outEntity.setId(dto.getId());
          outEntity.setNome(dto.getNome());
          outEntity.setDescrizione(dto.getDescrizione());
          outEntity.setDataInizioValidita(dto.getDataInizioValidita());
          outEntity.setDataFineValidita(dto.getDataFineValidita());
      }
  
      @Override
      protected boolean entityExists(Gruppo entity) {
          return entity != null &amp;&amp; entity.getId() &gt; 0;
      }
  
  }
  </code></pre>
  
  <p><strong>UPDATE #2</strong></p>
  
  <p>Following <strong>Łukasz L.</strong> suggestion, I added to all my crud methods a <code>flush()</code>. Now I get this exception <code>javax.persistence.TransactionRequiredException: no transaction is in progress</code>. What's wrong with my transaction declaration? it works fine with non-generic serices...</p>