1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package br.com.germantech.dao;

import java.lang.reflect.Field;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Id;

import org.apache.log4j.Logger;
import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
import org.eclipse.persistence.sessions.UnitOfWork;

import br.com.germantech.emf.FiscalEntityManagerFactory;

public class GermantechDAO {

  private static Logger log = Logger.getLogger(GermantechDAO.class);
  
  protected EntityManager em;
  protected EntityTransaction transaction;

  /**
   * Instantiates a new comics editor model.
   */
  public GermantechDAO() {
    em = FiscalEntityManagerFactory.createEntityManager();
    transaction = em.getTransaction();
  }

  /**
   * Close.
   */
  public void close() {
    em.close();
  }

  /**
   * Persist entity.
   *
   * @param entity the entity
   */
  private void persistEntity(Object entity) {
    em.persist(entity);
  }

  /**
   * Removes the entity.
   *
   * @param entity the entity
   */
  public void removeEntity(Object entity) {
    em.remove(entity);
  }
  
  /**
   * Deleta a entidade em questão
   * @param obj a entidade a ser removida
   * @throws Exception Caso não seja possível remover a entidade do banco
   */
  public void delete(Object obj) throws Exception {
    try {
      transaction.begin();
      em.remove(obj);
      transaction.commit();
    } catch (Exception e) {
      if(transaction.isActive())
        transaction.rollback();
      throw e;
    }
  }
  
  /**
   * Salva (ou atualiza) a entidade em questão, de acordo com a presença do Id
   * @param objeto
   * @throws Exception
   */
  public void saveOrUpdate(Object objeto) throws Exception{
    try {
      transaction.begin();
      if(hasId(objeto))
        em.merge(objeto);
      else
        persistEntity(objeto);
      transaction.commit();
    } catch (Exception e) {
      if(transaction.isActive())
        transaction.rollback();
      throw e;
    }
  }
  
  public void refresh() {
    em.clear();
  }

  /**
   * Checks if is dirty.
   *
   * @return true, if is dirty
   */
  public boolean isDirty() {
    UnitOfWork uow = ((EntityManagerImpl) em).getUnitOfWork();
    return uow.hasChanges();
  }
  
  /**
   * Verifica se a entidade em questão possui um Id. Método utilizado para escolher 
   * se a o esquema de persistência deve salvar ou atualizar o modelo
   * @param entity A entidade a ser verificada
   * @return <code>true</code> se a entidade possui Id
   * @throws Exception Caso algo de errado, uma exceção será lançada
   */
  public boolean hasId(Object entity) throws Exception{
    Class<?> clazz = entity.getClass();
    for(Field f : clazz.getDeclaredFields()){
      if(!f.isAccessible())
        f.setAccessible(true);
      if(f.isAnnotationPresent(Id.class)){
        if(f.get(entity) != null){
          log.info("ID found: "+f.get(entity));
          return true;
        }
      }
    }
    return false;
  }
}