1 /*
2    Copyright (c) 2015, 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, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 package testsuite.clusterj;
26 
27 import com.mysql.clusterj.DynamicObject;
28 import com.mysql.clusterj.ClusterJUserException;
29 import com.mysql.clusterj.Query;
30 
31 import com.mysql.clusterj.query.Predicate;
32 import com.mysql.clusterj.query.PredicateOperand;
33 import com.mysql.clusterj.query.QueryBuilder;
34 import com.mysql.clusterj.query.QueryDomainType;
35 import java.util.ArrayList;
36 import java.util.List;
37 import testsuite.clusterj.model.Employee;
38 
39 /** Test session.release(Object)
40  *
41  */
42 public class ReleaseTest extends AbstractClusterJModelTest {
43 
test()44     public void test() {
45         testReleaseStatic();
46         testReleaseDynamic();
47         testReleaseArray();
48         testReleaseIterable();
49         testReleaseFoundStatic();
50         testReleaseFoundDynamic();
51         testReleaseQueryStatic();
52         testReleaseQueryDynamic();
53         testReleaseNonPersistent();
54         failOnError();
55     }
56     Employee emp0;
57     Employee emp1;
58     Employee emp2;
59     Employee emp3;
60     Employee emp4;
61     Employee emp5;
62     Employee emp6;
63     Employee emp7;
64 
setEmployeeFields(Employee emp)65     Employee  setEmployeeFields(Employee emp) {
66         int id = emp.getId();
67         emp.setName("Employee " + id);
68         emp.setMagic(id);
69         emp.setAge(id);
70         return emp;
71     }
72 
73     @Override
localSetUp()74     public void localSetUp() {
75         createSessionFactory();
76         session = sessionFactory.getSession();
77         session.deletePersistentAll(Employee.class);
78         emp0 =  setEmployeeFields(session.newInstance(Employee.class, 0));
79         emp1 =  setEmployeeFields(session.newInstance(DynamicEmployee.class, 1));
80         emp2 =  setEmployeeFields(session.newInstance(Employee.class, 2));
81         emp3 =  setEmployeeFields(session.newInstance(DynamicEmployee.class, 3));
82         emp4 =  setEmployeeFields(session.newInstance(Employee.class, 4));
83         emp5 =  setEmployeeFields(session.newInstance(DynamicEmployee.class, 5));
84         emp6 =  setEmployeeFields(session.newInstance(Employee.class, 6));
85         emp7 =  setEmployeeFields(session.newInstance(DynamicEmployee.class, 7));
86         // make some instances persistent
87         session.makePersistent(new Employee[] {emp0, emp1, emp2, emp5, emp6, emp7});
88         // emp6 and emp7 are going to be found later
89         emp6 = null;
90         emp7 = null;
91         addTearDownClasses(Employee.class, DynamicEmployee.class);
92     }
93 
94     /** Test that getting a persistent field of a released object throws the proper exception
95      */
testGetId(Employee emp, String where)96     void testGetId(Employee emp, String where) {
97         // access getId of emp and verify that it throws the proper exception
98         try {
99             emp.getId();
100             error("getId for " + where + " failed to throw ClusterJUserException");
101         } catch (ClusterJUserException ex) {
102             // good catch: Cannot access object after release
103             String message = ex.getMessage();
104             errorIfNotEqual("wrong error message for " + where + ":" + message, true, message.contains("elease"));
105             // make sure that another release does not throw an exception
106             try {
107             session.release(emp);
108             } catch (Throwable t) {
109                 error("release for " + where + " incorrectly threw exception " + t.getMessage());
110             }
111         } catch (Throwable t) {
112             t.printStackTrace();
113             error("getId for " + where + " threw wrong exception " + t.getMessage());
114         }
115     }
116 
117     /** Test that setting a persistent field of a released object throws the proper exception
118      */
testSetId(Employee emp, String where)119     void testSetId(Employee emp, String where) {
120         // access getId of emp and verify that it throws the proper exception
121         try {
122             emp.setId(0);
123             error("setId for " + where + " failed to throw ClusterJUserException");
124         } catch (ClusterJUserException ex) {
125             // good catch: Cannot access object after release
126             String message = ex.getMessage();
127             errorIfNotEqual("wrong error message for " + where + ":" + message, true, message.contains("elease"));
128             // make sure that another release does not throw an exception
129             try {
130             session.release(emp);
131             } catch (Throwable t) {
132                 error("release for " + where + " incorrectly threw exception " + t.getMessage());
133             }
134         } catch (Throwable t) {
135             t.printStackTrace();
136             error("setId for " + where + " threw wrong exception " + t.getMessage());
137         }
138     }
139 
140     /** Test that makePersistent of a released object throws the proper exception
141      */
testMakePersistent(Employee emp, String where)142     void testMakePersistent(Employee emp, String where) {
143         // makePersistent emp and verify that it throws the proper exception
144         try {
145             session.makePersistent(emp);
146             error("makePersistent for " + where + " failed to throw ClusterJUserException");
147         } catch (ClusterJUserException ex) {
148             // good catch: Cannot access object after release
149             String message = ex.getMessage();
150             errorIfNotEqual("wrong error message for " + where + ":" + message, true, message.contains("elease"));
151             // make sure that another release does not throw an exception
152             try {
153             session.release(emp);
154             } catch (Throwable t) {
155                 error("release for " + where + " incorrectly threw exception " + t.getMessage());
156             }
157         } catch (Throwable t) {
158             error("makePersistent for " + where + " threw wrong exception " + t.getMessage());
159         }
160     }
161 
162     /** Test that SavePersistent of a released object throws the proper exception
163      */
testSavePersistent(Employee emp, String where)164     void testSavePersistent(Employee emp, String where) {
165         // savePersistent emp and verify that it throws the proper exception
166         try {
167             session.savePersistent(emp);
168             error("savePersistent for " + where + " failed to throw ClusterJUserException");
169         } catch (ClusterJUserException ex) {
170             // good catch: Cannot access object after release
171             String message = ex.getMessage();
172             errorIfNotEqual("wrong error message: " + message, true, message.contains("elease"));
173             // make sure that another release does not throw an exception
174             try {
175             session.release(emp);
176             } catch (Throwable t) {
177                 error("release for " + where + " incorrectly threw exception " + t.getMessage());
178             }
179         } catch (Throwable t) {
180             error("savePersistent for " + where + " threw wrong exception " + t.getMessage());
181         }
182     }
183 
184     /** Test that updatePersistent of a released object throws the proper exception
185      */
testUpdatePersistent(Employee emp, String where)186     void testUpdatePersistent(Employee emp, String where) {
187         // updatePersistent emp and verify that it throws the proper exception
188         try {
189             session.updatePersistent(emp);
190             error("getId for " + where + " failed to throw ClusterJUserException");
191         } catch (ClusterJUserException ex) {
192             // good catch: Cannot access object after release
193             String message = ex.getMessage();
194             errorIfNotEqual("wrong error message: " + message, true, message.contains("elease"));
195             // make sure that another release does not throw an exception
196             try {
197             session.release(emp);
198             } catch (Throwable t) {
199                 error("release for " + where + " incorrectly threw exception " + t.getMessage());
200             }
201         } catch (Throwable t) {
202             error("updatePersistent for " + where + " threw wrong exception " + t.getMessage());
203         }
204     }
205 
206     /** Test that deletePersistent of a released object throws the proper exception
207      */
testDeletePersistent(Employee emp, String where)208     void testDeletePersistent(Employee emp, String where) {
209         // deletePersistent emp and verify that it throws the proper exception
210         try {
211             session.deletePersistent(emp);
212             error("deletePersistent for " + where + " failed to throw ClusterJUserException");
213         } catch (ClusterJUserException ex) {
214             // good catch: Cannot access object after release
215             String message = ex.getMessage();
216             errorIfNotEqual("wrong error message: " + message, true, message.contains("elease"));
217             try {
218             session.release(emp);
219             } catch (Throwable t) {
220                 error("release for " + where + " incorrectly threw exception " + t.getMessage());
221             }
222         } catch (Throwable t) {
223             error("deletePersistent for " + where + " threw wrong exception " + t.getMessage());
224         }
225     }
226 
227     /** Test that release of non-persistent types throws the proper exception
228      */
testNonPersistentRelease(Object object, String where)229     void testNonPersistentRelease(Object object, String where) {
230         try {
231             session.release(object);
232             error("release for " +  where + " failed to throw ClusterJUserException");
233         } catch (ClusterJUserException ex) {
234             // good catch: release argument must be a persistent type
235             String message = ex.getMessage();
236             errorIfNotEqual("wrong error message: " + message, true, message.contains("elease"));
237         } catch (Throwable t) {
238             error("release for Integer threw the wrong exception: " + t.getMessage());
239         }
240     }
241 
242     /** Test releasing resources for static class Employee. */
testReleaseStatic()243     protected void testReleaseStatic() {
244         // release employee 0 and make sure that accessing it throws an exception
245         Employee result = session.release(emp0);
246         if (result != emp0) {
247             error("for static object, result of release does not equal parameter.");
248         }
249         testGetId(emp0, "static object");
250         testSetId(emp0, "static object");
251         testMakePersistent(emp0, "static object");
252         testSavePersistent(emp0, "static object");
253         testUpdatePersistent(emp0, "static object");
254         testDeletePersistent(emp0, "static object");
255     }
256 
testReleaseDynamic()257     protected void testReleaseDynamic() {
258         // release employee 1 and make sure that accessing it throws an exception
259         Employee result = session.release(emp1);
260         if (result != emp1) {
261             error("for dynamic object, result of release does not equal parameter.");
262         }
263         testGetId(emp1, "dynamic object");
264         testSetId(emp1, "dynamic object");
265         testMakePersistent(emp1, "dynamic object");
266         testSavePersistent(emp1, "dynamic object");
267         testUpdatePersistent(emp1, "dynamic object");
268         testDeletePersistent(emp1, "dynamic object");
269     }
270 
271     /** Test releasing resources for Iterable<Employee>. */
testReleaseIterable()272     protected void testReleaseIterable() {
273         // release employee 2 and 3 list and make sure that accessing them throws an exception
274         List<Object> list = new ArrayList<Object>();
275         list.add(emp2);
276         list.add(emp3);
277         List<Object> result = null;
278         try {
279             result = session.release(list);
280         } catch (Throwable t) {
281             t.printStackTrace();
282         }
283         if (list != result) error("session.release list did not return argument");
284         testGetId(emp2, "static object in list");
285         testSetId(emp2, "static object in list");
286         testMakePersistent(emp2, "static object in list");
287         testSavePersistent(emp2, "static object in list");
288         testUpdatePersistent(emp2, "static object in list");
289         testDeletePersistent(emp2, "static object in list");
290         testGetId(emp3, "dynamic object in list");
291         testSetId(emp3, "dynamic object in list");
292         testMakePersistent(emp3, "dynamic object in list");
293         testSavePersistent(emp3, "dynamic object in list");
294         testUpdatePersistent(emp3, "dynamic object in list");
295         testDeletePersistent(emp3, "dynamic object in list");
296     }
297 
298     /** Test releasing resources for Employee[]. */
testReleaseArray()299     protected void testReleaseArray() {
300         // release employee array 4 and 5 and make sure that accessing them throws an exception
301         Employee[] array = new Employee[] {emp4, emp5};
302         Employee[] result = null;
303         try {
304             result = session.release(array);
305         } catch (Throwable t) {
306             t.printStackTrace();
307         }
308         if (array != result) error("session.release array did not return argument");
309         testGetId(emp4, "static object in array");
310         testSetId(emp4, "static object in array");
311         testMakePersistent(emp4, "static object in array");
312         testSavePersistent(emp4, "static object in array");
313         testUpdatePersistent(emp4, "static object in array");
314         testDeletePersistent(emp4, "static object in array");
315         testGetId(emp5, "dynamic object in array");
316         testSetId(emp5, "dynamic object in array");
317         testMakePersistent(emp5, "dynamic object in array");
318         testSavePersistent(emp5, "dynamic object in array");
319         testUpdatePersistent(emp5, "dynamic object in array");
320         testDeletePersistent(emp5, "dynamic object in array");
321     }
322 
323     /** Test releasing object of non-persistent type */
testReleaseNonPersistent()324     protected void testReleaseNonPersistent() {
325         testNonPersistentRelease(new Integer(1), "new Integer(1)");
326         testNonPersistentRelease(new Integer[] {1, 2}, "new Integer[] {1, 2}");
327     }
328 
329     /** Test releasing static object acquired via find */
testReleaseFoundStatic()330     protected void testReleaseFoundStatic() {
331         emp6 = session.find(Employee.class, 6);
332         session.release(emp6);
333         testGetId(emp6, "static found object");
334         testSetId(emp6, "static found object");
335         testMakePersistent(emp6, "static found object");
336         testSavePersistent(emp6, "static found object");
337         testUpdatePersistent(emp6, "static found object");
338         testDeletePersistent(emp6, "static found object");
339     }
340 
341     /** Test releasing dynamic object acquired via find */
testReleaseFoundDynamic()342     protected void testReleaseFoundDynamic() {
343         emp7 = session.find(DynamicEmployee.class, 7);
344         session.release(emp7);
345         testGetId(emp7, "dynamic found object");
346         testSetId(emp7, "dynamic found object");
347         testMakePersistent(emp7, "dynamic found object");
348         testSavePersistent(emp7, "dynamic found object");
349         testUpdatePersistent(emp7, "dynamic found object");
350         testDeletePersistent(emp7, "dynamic found object");
351     }
352 
353     /** Test releasing static objects acquired via query */
testReleaseQueryStatic()354     protected void testReleaseQueryStatic() {
355         QueryBuilder builder = session.getQueryBuilder();
356         QueryDomainType dobj = builder.createQueryDefinition(Employee.class);
357         // parameter name
358         PredicateOperand id_low = dobj.param("id_low");
359         PredicateOperand id_high = dobj.param("id_high");
360         // property name
361         PredicateOperand column = dobj.get("id");
362         // compare the column with the parameters
363         Predicate compare = column.between(id_low, id_high);
364         // set the where clause into the query
365         dobj.where(compare);
366         // create a query instance
367         Query query = session.createQuery(dobj);
368 
369         // set the parameter values
370         query.setParameter("id_low", 0);
371         query.setParameter("id_high", 2);
372         // get the results
373         List<Employee> results = query.getResultList();
374         errorIfNotEqual("Static query wrong result size", 3, results.size());
375         // release the results
376         session.release(results);
377         for (Employee emp: results) {
378             testGetId(emp, "static query object");
379             testSetId(emp, "static query object");
380             testMakePersistent(emp, "static query object");
381             testSavePersistent(emp, "static query object");
382             testUpdatePersistent(emp, "static query object");
383             testDeletePersistent(emp, "static query object");
384         }
385     }
386 
387     /** Test releasing dynamic objects acquired via query */
testReleaseQueryDynamic()388     protected void testReleaseQueryDynamic() {
389         QueryBuilder builder = session.getQueryBuilder();
390         QueryDomainType dobj = builder.createQueryDefinition(DynamicEmployee.class);
391         // parameter name
392         PredicateOperand id_low = dobj.param("id_low");
393         PredicateOperand id_high = dobj.param("id_high");
394         // property name
395         PredicateOperand column = dobj.get("id");
396         // compare the column with the parameters
397         Predicate compare = column.between(id_low, id_high);
398         // set the where clause into the query
399         dobj.where(compare);
400         // create a query instance
401         Query query = session.createQuery(dobj);
402 
403         // set the parameter values
404         query.setParameter("id_low", 0);
405         query.setParameter("id_high", 2);
406         // get the results
407         List<Employee> results = query.getResultList();
408         errorIfNotEqual("Dynamic query wrong result size", 3, results.size());
409         // release the results
410         session.release(results);
411         for (Employee emp: results) {
412             testGetId(emp, "dynamic query object");
413             testSetId(emp, "dynamic query object");
414             testMakePersistent(emp, "dynamic query object");
415             testSavePersistent(emp, "dynamic query object");
416             testUpdatePersistent(emp, "dynamic query object");
417             testDeletePersistent(emp, "dynamic query object");
418         }
419     }
420 
421     /** Dynamic Employee class */
422     public static class DynamicEmployee  extends DynamicObject  implements Employee {
423 
424         @Override
table()425         public String table() {
426             return "t_basic";
427         }
getId()428         public int getId() {
429             return (Integer)get(0);
430         }
setId(int id)431         public void setId(int id) {
432             set(0, id);
433         }
434 
getName()435         public String getName() {
436             return (String)get(1);
437         }
setName(String name)438         public void setName(String name) {
439             set(1, name);
440         }
441 
getMagic()442         public int getMagic() {
443             return (Integer)get(2);
444         }
setMagic(int magic)445         public void setMagic(int magic) {
446             set(2, magic);
447         }
448 
getAge()449         public Integer getAge() {
450             return (Integer)get(3);
451         }
setAge(Integer age)452         public void setAge(Integer age) {
453             set(3, age);
454         }
455     }
456 
457 }
458