1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
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 }