MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AbstractJPABaseTest.java
1 /*
2  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 package com.mysql.clusterj.jpatest;
19 
20 import java.sql.Connection;
21 import java.sql.PreparedStatement;
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.util.ArrayList;
25 import java.util.Calendar;
26 import java.util.List;
27 import java.util.TimeZone;
28 
29 import javax.persistence.Query;
30 
31 import org.apache.openjpa.persistence.OpenJPAEntityManager;
32 
33 import com.mysql.clusterj.jpatest.model.Employee;
34 import com.mysql.clusterj.jpatest.model.IdBase;
35 
39 public abstract class AbstractJPABaseTest extends SingleEMTestCase {
40 
42  protected static TimeZone localSystemTimeZone = TimeZone.getDefault();
43 
45  protected Connection connection;
46 
48  private ColumnDescriptor[] columnDescriptors = getColumnDescriptors();
49 
51  List<IdBase> instances = new ArrayList<IdBase>();
52 
54  private List<Object[]> expected = null;
55 
57  protected static boolean debug;
58 
59  public AbstractJPABaseTest() {
60  debug = getDebug();
61  }
62 
63  protected void getConnection() {
64  connection = (Connection) ((OpenJPAEntityManager)em).getConnection();
65  setAutoCommit(connection, false);
66  }
67 
68  protected void setAutoCommit(Connection connection, boolean b) {
69  try {
70  connection.setAutoCommit(false);
71  } catch (SQLException e) {
72  throw new RuntimeException("setAutoCommit failed", e);
73  }
74  }
75 
76  public void deleteAll() {
77  // delete all instances without verifying
78  em = emf.createEntityManager();
79  begin();
80  for (int i = 0; i < getNumberOfEmployees(); ++i) {
81  Employee e = em.find(Employee.class, i);
82  if (e != null) {
83  em.remove(e);
84  }
85  }
86  commit();
87  em.close();
88  }
89  public void verifyDeleteAll() {
90  em = emf.createEntityManager();
91  begin();
92  for (int i = 0; i < getNumberOfEmployees(); ++i) {
93  Employee e = em.find(Employee.class, i);
94  if (e != null) {
95  error("Entity exists after being removed: " + i);
96  }
97  }
98  commit();
99  failOnError();
100  em.close();
101  }
102  public void createAll() {
103  em = emf.createEntityManager();
104  begin();
105  for (int i = 0; i < getNumberOfEmployees(); ++i) {
106  Employee e = new Employee();
107  e.setId(i);
108  e.setAge(i);
109  e.setMagic(i);
110  e.setName("Employee " + i);
111  em.persist(e);
112  }
113  commit();
114  em.close();
115  }
116 
117  public void findAll() {
118  em = emf.createEntityManager();
119  begin();
120  for (int i = 0; i < getNumberOfEmployees(); ++i) {
121  Employee e = em.find(Employee.class, i);
122  verifyEmployee(e, 0);
123  }
124  commit();
125  em.close();
126  }
127 
128  public void updateThenVerifyAll() {
129  em = emf.createEntityManager();
130  begin();
131  for (int i = 0; i < getNumberOfEmployees(); ++i) {
132  Employee e = em.find(Employee.class, i);
133  e.setAge(i + 1);
134  verifyEmployee(e, 1);
135  }
136  commit();
137  begin();
138  for (int i = 0; i < getNumberOfEmployees(); ++i) {
139  Employee e = em.find(Employee.class, i);
140  verifyEmployee(e, 1);
141  }
142  commit();
143  em.close();
144  }
145 
146  public void deleteThenVerifyAll() {
147  em = emf.createEntityManager();
148  begin();
149  for (int i = 0; i < getNumberOfEmployees(); ++i) {
150  Employee e = em.find(Employee.class, i);
151  verifyEmployee(e, 1);
152  em.remove(e);
153  }
154  commit();
155  begin();
156  for (int i = 0; i < getNumberOfEmployees(); ++i) {
157  Employee e = em.find(Employee.class, i);
158  if (e != null) {
159  error("Entity exists after being removed: " + i);
160  }
161  }
162  commit();
163  em.close();
164  }
165 
166  protected void verifyEmployee(Employee e, int updateOffset) {
167  int i = e.getId();
168  errorIfNotEqual("Error in age", i + updateOffset, e.getAge().intValue());
169  errorIfNotEqual("Error in magic", i, e.getMagic());
170  errorIfNotEqual("Error in name", "Employee " + i, e.getName());
171  }
172  protected int getNumberOfEmployees() {
173  return 1;
174  }
175 
185  protected static long getMillisFor(int year, int month, int day, int hour, int minute, int second) {
186  Calendar calendar = Calendar.getInstance();
187  calendar.clear();
188  calendar.set(Calendar.YEAR, year);
189  calendar.set(Calendar.MONTH, month);
190  calendar.set(Calendar.DATE, day);
191  calendar.set(Calendar.HOUR, hour);
192  calendar.set(Calendar.MINUTE, minute);
193  calendar.set(Calendar.SECOND, second);
194  calendar.set(Calendar.MILLISECOND, 0);
195  long result = calendar.getTimeInMillis();
196  return result;
197  }
198 
206  protected static long getMillisFor(int year, int month, int day) {
207  Calendar calendar = Calendar.getInstance();
208  calendar.clear();
209  calendar.set(Calendar.YEAR, year);
210  calendar.set(Calendar.MONTH, month);
211  calendar.set(Calendar.DATE, day);
212  calendar.set(Calendar.HOUR, 0);
213  calendar.set(Calendar.MINUTE, 0);
214  calendar.set(Calendar.SECOND, 0);
215  calendar.set(Calendar.MILLISECOND, 0);
216  long result = calendar.getTimeInMillis();
217  return result;
218  }
219 
229  protected static long getMillisFor(int days, int hour, int minute, int second) {
230  Calendar calendar = Calendar.getInstance();
231  calendar.clear();
232  calendar.set(Calendar.DATE, days + 1);
233  calendar.set(Calendar.HOUR, hour);
234  calendar.set(Calendar.MINUTE, minute);
235  calendar.set(Calendar.SECOND, second);
236  calendar.set(Calendar.MILLISECOND, 0);
237  long result = calendar.getTimeInMillis();
238  return result;
239  }
240 
247  protected static void resetLocalSystemDefaultTimeZone(Connection connection) {
248  try {
249  PreparedStatement statement = connection.prepareStatement("select @@global.time_zone, @@global.system_time_zone, @@session.time_zone");
250  ResultSet rs = statement.executeQuery();
251  // there are two columns in the result
252  rs.next();
253  String globalTimeZone = rs.getString(1);
254  String globalSystemTimeZone = rs.getString(2);
255  String sessionTimeZone = rs.getString(3);
256  if (debug) System.out.println("Global time zone: " + globalTimeZone +
257  " Global system time zone: " + globalSystemTimeZone +" Session time zone: " + sessionTimeZone);
258  connection.commit();
259  if ("SYSTEM".equalsIgnoreCase(globalTimeZone)) {
260  globalTimeZone = globalSystemTimeZone;
261  } else {
262  globalTimeZone = "GMT" + globalTimeZone;
263  }
264  localSystemTimeZone = TimeZone.getTimeZone(globalTimeZone);
265  if (debug) System.out.println("Local system time zone set to: " + globalTimeZone + "(" + localSystemTimeZone + ")");
266  TimeZone.setDefault(localSystemTimeZone);
267  // get a new connection after setting local default time zone
268  // because a connection contains a session calendar used to create Timestamp instances
269  connection.close();
270  } catch (SQLException e) {
271  throw new RuntimeException("setServerTimeZone failed", e);
272  }
273  }
274 
279  protected static class ColumnDescriptor {
280 
281  private String columnName;
282 
283  protected InstanceHandler instanceHandler;
284 
285  public String getColumnName() {
286  return columnName;
287  }
288 
289  public Object getResultSetValue(ResultSet rs, int j) throws SQLException {
290  return instanceHandler.getResultSetValue(rs, j);
291  }
292 
293  public Object getFieldValue(IdBase instance) {
294  return instanceHandler.getFieldValue(instance);
295  }
296 
297  public void setFieldValue(IdBase instance, Object value) {
298  this.instanceHandler.setFieldValue(instance, value);
299  }
300 
301  public void setPreparedStatementValue(PreparedStatement preparedStatement, int j, Object value)
302  throws SQLException {
303  instanceHandler.setPreparedStatementValue(preparedStatement, j, value);
304  }
305 
306  protected ColumnDescriptor(String name, InstanceHandler instanceHandler) {
307  this.columnName = name;
308  this.instanceHandler = instanceHandler;
309  }
310  }
311 
312  protected interface InstanceHandler {
313  void setFieldValue(IdBase instance, Object value);
314  Object getResultSetValue(ResultSet rs, int j)
315  throws SQLException;
316  Object getFieldValue(IdBase instance);
317  public void setPreparedStatementValue(PreparedStatement preparedStatement, int j, Object value)
318  throws SQLException;
319  }
320 
322  protected boolean getDebug() {
323  return false;
324  }
325 
327  protected List<Object[]> getExpected() {
328  return expected;
329  }
330 
332  protected String getTableName() {
333  return null;
334  }
335 
337  protected int getNumberOfInstances() {
338  return 0;
339  }
340 
342  protected ColumnDescriptor[] getColumnDescriptors() {
343  return null;
344  }
345 
347  protected IdBase getNewInstance(Class<? extends IdBase> modelClass) {
348  return null;
349  }
350 
352  protected Class<? extends IdBase> getModelClass() {
353  return null;
354  }
355 
357  protected Object getColumnValue(int i, int j) {
358  return null;
359  }
360 
366  protected void generateInstances(ColumnDescriptor[] columnDescriptors) {
367  Class<? extends IdBase> modelClass = getModelClass();
368  expected = new ArrayList<Object[]>();
369  instances = new ArrayList<IdBase>();
370  IdBase instance = null;
371  int numberOfInstances = getNumberOfInstances();
372  for (int i = 0; i < numberOfInstances; ++i) {
373  // create the instance
374  instance = getNewInstance(modelClass);
375  instance.setId(i);
376  // create the expected result row
377  int j = 0;
378  for (ColumnDescriptor columnDescriptor: columnDescriptors) {
379  Object value = getColumnValue(i, j);
380  // set the column value in the instance
381  columnDescriptor.setFieldValue(instance, value);
382  // set the column value in the expected result
383  if (debug) System.out.println("generateInstances set field " + columnDescriptor.getColumnName() + " to value " + value);
384  ++j;
385  }
386  instances.add(instance);
387  Object[] expectedRow = createRow(columnDescriptors, instance);
388  expected.add(expectedRow);
389  }
390  if (debug) System.out.println("Created " + instances.size() + " instances.");
391  }
392 
399  protected void verify(String where, List<Object[]> expecteds, List<Object[]> actuals) {
400  for (int i = 0; i < expecteds.size(); ++i) {
401  Object[] expected = expecteds.get(i);
402  Object[] actual = actuals.get(i);
403  errorIfNotEqual(where + " got failure on id for row " + i, i, actual[0]);
404  for (int j = 1; j < expected.length; ++j) {
405  errorIfNotEqual(where + " got failure to match column data for row "
406  + i + " column " + j,
407  expected[j], actual[j]);
408  }
409  }
410  }
411 
412  protected void removeAll(Class<? extends IdBase> modelClass) {
413  Query query = em.createQuery("DELETE FROM " + modelClass.getSimpleName());
414  em.getTransaction().begin();
415  query.executeUpdate();
416  em.getTransaction().commit();
417  }
418 
419  private void removeAll(String tableName) {
420  getConnection();
421  try {
422  PreparedStatement statement = connection.prepareStatement("DELETE FROM " + tableName);
423  statement.execute();
424  connection.commit();
425  } catch (SQLException e) {
426  // TODO Auto-generated catch block
427  e.printStackTrace();
428  }
429  }
430 
432  protected void writeJDBCreadJPA() {
433  generateInstances(columnDescriptors);
434  removeAll(getTableName());
435  List<Object[]> result = null;
436  writeToJDBC(columnDescriptors, instances);
437  result = readFromJPA(columnDescriptors);
438  verify("writeJDBCreadJPA", getExpected(), result);
439  }
440 
442  protected void writeJDBCreadJDBC() {
443  generateInstances(columnDescriptors);
444  removeAll(getTableName());
445  List<Object[]> result = null;
446  writeToJDBC(columnDescriptors, instances);
447  result = readFromJDBC(columnDescriptors);
448  verify("writeJDBCreadJDBC", getExpected(), result);
449  }
450 
452  protected void writeJPAreadJPA() {
453  generateInstances(columnDescriptors);
454  removeAll(getModelClass());
455  List<Object[]> result = null;
456  writeToJPA(columnDescriptors, instances);
457  result = readFromJPA(columnDescriptors);
458  verify("writeJPAreadJPA", getExpected(), result);
459  }
460 
462  protected void writeJPAreadJDBC() {
463  generateInstances(columnDescriptors);
464  removeAll(getTableName());
465  List<Object[]> result = null;
466  writeToJPA(columnDescriptors, instances);
467  result = readFromJDBC(columnDescriptors);
468  verify("writeJPAreadJDBC", getExpected(), result);
469  }
470 
472  protected void writeToJPA(ColumnDescriptor[] columnDescriptors, List<IdBase> instances) {
473  em.getTransaction().begin();
474  for (IdBase instance: instances) {
475  em.persist(instance);
476  }
477  em.getTransaction().commit();
478  }
479 
481  protected void writeToJDBC(ColumnDescriptor[] columnDescriptors, List<IdBase> instances) {
482  String tableName = getTableName();
483  StringBuffer buffer = new StringBuffer("INSERT INTO ");
484  buffer.append(tableName);
485  buffer.append(" (id");
486  for (ColumnDescriptor columnDescriptor: columnDescriptors) {
487  buffer.append(", ");
488  buffer.append(columnDescriptor.getColumnName());
489  }
490  buffer.append(") VALUES (?");
491  for (ColumnDescriptor columnDescriptor: columnDescriptors) {
492  buffer.append(", ?");
493  }
494  buffer.append(")");
495  String statement = buffer.toString();
496  if (debug) System.out.println(statement);
497 
498  PreparedStatement preparedStatement = null;
499  int i = 0;
500  try {
501  preparedStatement = connection.prepareStatement(statement);
502  if (debug) System.out.println(preparedStatement.toString());
503  for (i = 0; i < instances.size(); ++i) {
504  IdBase instance = instances.get(i);
505  preparedStatement.setInt(1, instance.getId());
506  int j = 2;
507  for (ColumnDescriptor columnDescriptor: columnDescriptors) {
508  Object value = columnDescriptor.getFieldValue(instance);
509  columnDescriptor.setPreparedStatementValue(preparedStatement, j++, value);
510  if (debug) System.out.println("writeToJDBC set column: " + columnDescriptor.getColumnName() + " to value: " + value);
511  }
512  preparedStatement.execute();
513  }
514  connection.commit();
515  } catch (SQLException e) {
516  throw new RuntimeException("Failed to insert " + tableName + " at instance " + i, e);
517  }
518  }
519 
521  protected List<Object[]> readFromJPA(ColumnDescriptor[] columnDescriptors) {
522  Class<? extends IdBase> modelClass = getModelClass();
523  List<Object[]> result = new ArrayList<Object[]>();
524  em.getTransaction().begin();
525  for (int i = 0; i < getNumberOfInstances() ; ++i) {
526  IdBase instance = em.find(modelClass, i);
527  if (instance != null) {
528  Object[] row = createRow(columnDescriptors, instance);
529  result.add(row);
530  }
531  }
532  em.getTransaction().commit();
533  if (debug) System.out.println("readFromJPA: " + dump(result));
534  return result;
535  }
536 
538  protected List<Object[]> readFromJDBC(ColumnDescriptor[] columnDescriptors) {
539  String tableName = getTableName();
540  List<Object[]> result = new ArrayList<Object[]>();
541  StringBuffer buffer = new StringBuffer("SELECT id");
542  for (ColumnDescriptor columnDescriptor: columnDescriptors) {
543  buffer.append(", ");
544  buffer.append(columnDescriptor.getColumnName());
545  }
546  buffer.append(" FROM ");
547  buffer.append(tableName);
548  buffer.append(" ORDER BY ID");
549  String statement = buffer.toString();
550  if (debug) System.out.println(statement);
551  PreparedStatement preparedStatement = null;
552  int i = 0;
553  try {
554  preparedStatement = connection.prepareStatement(statement);
555  ResultSet rs = preparedStatement.executeQuery();
556  while (rs.next()) {
557  Object[] row = new Object[columnDescriptors.length + 1];
558  int j = 1;
559  row[0] = rs.getInt(1);
560  for (ColumnDescriptor columnDescriptor: columnDescriptors) {
561  row[j] = columnDescriptor.getResultSetValue(rs, j + 1);
562  ++j;
563  }
564  ++i;
565  result.add(row);
566  }
567  connection.commit();
568  } catch (SQLException e) {
569  throw new RuntimeException("Failed to read " + tableName + " at instance " + i, e);
570  }
571  if (debug) System.out.println("readFromJDBC: " + dump(result));
572  return result;
573  }
574 
580  private Object[] createRow(ColumnDescriptor[] columnDescriptors,
581  IdBase instance) {
582  Object[] row = new Object[columnDescriptors.length + 1];
583  row[0] = instance.getId();
584  int j = 1;
585  for (ColumnDescriptor columnDescriptor: columnDescriptors) {
586  row[j++] = columnDescriptor.getFieldValue(instance);
587  }
588  return row;
589  }
590 
592  private String dump(List<Object[]> results) {
593  StringBuffer result = new StringBuffer(results.size() + " rows\n");
594  for (Object[] row: results) {
595  result.append("Id: ");
596  for (Object column: row) {
597  result.append(column);
598  result.append(' ');
599  }
600  result.append('\n');
601  }
602  return result.toString();
603  }
604 
605 }