View Javadoc

1   /*
2    * Sonar, entreprise quality control tool.
3    * Copyright (C) 2007-2008 Hortis-GRC SA
4    * mailto:be_agile HAT hortis DOT ch
5    *
6    * Sonar is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 3 of the License, or (at your option) any later version.
10   *
11   * Sonar is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with Sonar; if not, write to the Free Software
18   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
19   */
20  package org.sonar.commons.database;
21  
22  import javax.persistence.EntityManager;
23  import javax.persistence.NoResultException;
24  import javax.persistence.Query;
25  
26  public class BatchDatabaseManager implements DatabaseManager {
27    // IMPORTANT : this value must be the same than the property hibernate.jdbc.batch_size from /META-INF/persistence.xml :
28    public static final int BATCH_SIZE = 100;
29  
30    private DatabaseConnector connector;
31    private EntityManager entityManager = null;
32    private int index = 0;
33    private boolean inTransaction = false;
34  
35    public BatchDatabaseManager(DatabaseConnector connector) {
36      this.connector = connector;
37    }
38  
39    public EntityManager getEntityManager() {
40      return entityManager;
41    }
42  
43  
44    public void start() {
45      entityManager = connector.createEntityManager();
46      index = 0;
47    }
48  
49    public void stop() {
50      commit();
51      if (entityManager != null && entityManager.isOpen()) {
52        entityManager.clear();
53        entityManager.close();
54        entityManager = null;
55      }
56    }
57  
58    public void commit() {
59      if (entityManager != null && inTransaction) {
60        flush();
61        if (entityManager.getTransaction().getRollbackOnly()) {
62          entityManager.getTransaction().rollback();
63        } else {
64          entityManager.getTransaction().commit();
65        }
66        inTransaction = false;
67        index = 0;
68      }
69    }
70  
71    public void rollback() {
72      if (entityManager != null && inTransaction) {
73        entityManager.getTransaction().rollback();
74        inTransaction = false;
75        index = 0;
76      }
77    }
78  
79  
80    public Object save(Object model) {
81      startTransaction();
82      entityManager.persist(model);
83      if (++index % BATCH_SIZE == 0) {
84        flush();
85      }
86      return model;
87    }
88  
89    public Object merge(Object model) {
90      startTransaction();
91      return entityManager.merge(model);
92    }
93  
94    public void remove(Object model) {
95      startTransaction();
96      entityManager.remove(model);
97      if (++index % BATCH_SIZE == 0) {
98        flush();
99      }
100   }
101 
102   public <T> T reattach(Class<T> entityClass, Object primaryKey) {
103     startTransaction();
104     return entityManager.getReference(entityClass, primaryKey);
105   }
106 
107   private void startTransaction() {
108     if (!inTransaction) {
109       entityManager.getTransaction().begin();
110       inTransaction = true;
111     }
112   }
113 
114   private void flush() {
115     entityManager.flush();
116     entityManager.clear();
117   }
118 
119   public Query createQuery(String hql) {
120     startTransaction();
121     return entityManager.createQuery(hql);
122   }
123 
124   public Query createNamedQuery(String hql) {
125     startTransaction();
126     return entityManager.createNamedQuery(hql);
127   }
128 
129   public Object getSingleResult(Query query, Object defaultValue) {
130     try {
131       return query.getSingleResult();
132     }
133     catch (NoResultException ex) {
134       return defaultValue;
135     }
136   }
137 }