/tests/com/google/appengine/datanucleus/jdo/JDOAttachDetachTest.java

http://datanucleus-appengine.googlecode.com/ · Java · 329 lines · 276 code · 27 blank · 26 comment · 0 complexity · 1580e926fadeb769c6c298220b9d34ff MD5 · raw file

  1. /*
  2. * /**********************************************************************
  3. * Copyright (c) 2009 Google Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. * **********************************************************************/
  17. package com.google.appengine.datanucleus.jdo;
  18. import com.google.appengine.api.datastore.Entity;
  19. import com.google.appengine.api.datastore.EntityNotFoundException;
  20. import com.google.appengine.api.datastore.KeyFactory;
  21. import com.google.appengine.datanucleus.Utils;
  22. import com.google.appengine.datanucleus.test.jdo.BidirectionalChildListJDO;
  23. import com.google.appengine.datanucleus.test.jdo.DetachableJDO;
  24. import com.google.appengine.datanucleus.test.jdo.DetachableWithMultiValuePropsJDO;
  25. import com.google.appengine.datanucleus.test.jdo.Flight;
  26. import com.google.appengine.datanucleus.test.jdo.HasOneToManyListJDO;
  27. import java.io.ByteArrayInputStream;
  28. import java.io.ByteArrayOutputStream;
  29. import java.io.IOException;
  30. import java.io.ObjectInputStream;
  31. import java.io.ObjectOutputStream;
  32. import java.io.Serializable;
  33. import java.util.Date;
  34. import java.util.List;
  35. import javax.jdo.JDOHelper;
  36. import javax.jdo.JDOObjectNotFoundException;
  37. import javax.jdo.ObjectState;
  38. /**
  39. * @author Max Ross <maxr@google.com>
  40. */
  41. public class JDOAttachDetachTest extends JDOTestCase {
  42. private <T extends Serializable> T toBytesAndBack(T obj)
  43. throws IOException, ClassNotFoundException {
  44. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  45. ObjectOutputStream oos = new ObjectOutputStream(baos);
  46. oos.writeObject(obj);
  47. ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  48. ObjectInputStream ois = new ObjectInputStream(bais);
  49. return (T) ois.readObject();
  50. }
  51. public void testSimpleSerializeWithTxns()
  52. throws IOException, ClassNotFoundException, EntityNotFoundException {
  53. pm.setDetachAllOnCommit(true);
  54. beginTxn();
  55. DetachableJDO pojo = new DetachableJDO();
  56. pojo.setVal("yar");
  57. Date now = new Date();
  58. pojo.setDate(now);
  59. pm.makePersistent(pojo);
  60. commitTxn();
  61. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  62. assertEquals(Date.class, pojo.getDate().getClass());
  63. pm.close();
  64. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  65. pm = pmf.getPersistenceManager();
  66. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  67. pojo = toBytesAndBack(pojo);
  68. assertEquals("yar", pojo.getVal());
  69. assertEquals(now, pojo.getDate());
  70. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  71. beginTxn();
  72. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  73. pojo.setVal("not yar");
  74. Date newDate = new Date(pojo.getDate().getTime() + 1);
  75. pojo.getDate().setTime(newDate.getTime());
  76. assertEquals(ObjectState.DETACHED_DIRTY, JDOHelper.getObjectState(pojo));
  77. pm.makePersistent(pojo);
  78. commitTxn();
  79. Entity e = ds.get(KeyFactory.createKey(DetachableJDO.class.getSimpleName(), pojo.getId()));
  80. assertEquals("not yar", e.getProperty("val"));
  81. assertEquals(newDate, e.getProperty("date"));
  82. }
  83. public void testSimpleSerializeWithoutTxns() throws Exception {
  84. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  85. pm.setDetachAllOnCommit(true);
  86. DetachableJDO pojo = new DetachableJDO();
  87. pojo.setVal("yar");
  88. Date now = new Date();
  89. pojo.setDate(now);
  90. pm.makePersistent(pojo);
  91. // DN3 changes this from P_NEW to DETACHED_CLEAN since detachAllOnCommit
  92. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  93. pm.close();
  94. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  95. assertEquals(Date.class, pojo.getDate().getClass());
  96. pm = pmf.getPersistenceManager();
  97. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  98. pojo = toBytesAndBack(pojo);
  99. assertEquals("yar", pojo.getVal());
  100. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  101. pojo.setVal("not yar");
  102. Date newDate = new Date(pojo.getDate().getTime() + 1);
  103. pojo.getDate().setTime(newDate.getTime());
  104. assertEquals(ObjectState.DETACHED_DIRTY, JDOHelper.getObjectState(pojo));
  105. pm.makePersistent(pojo);
  106. pm.close();
  107. Entity e = ds.get(KeyFactory.createKey(DetachableJDO.class.getSimpleName(), pojo.getId()));
  108. assertEquals("not yar", e.getProperty("val"));
  109. assertEquals(newDate, e.getProperty("date"));
  110. }
  111. public void testSerializeWithMultiValueProps() throws Exception {
  112. pm.setDetachAllOnCommit(true);
  113. beginTxn();
  114. DetachableWithMultiValuePropsJDO pojo = new DetachableWithMultiValuePropsJDO();
  115. pojo.setStrList(Utils.newArrayList("c", "d"));
  116. pm.makePersistent(pojo);
  117. commitTxn();
  118. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  119. pm.close();
  120. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  121. pm = pmf.getPersistenceManager();
  122. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  123. pojo = toBytesAndBack(pojo);
  124. assertEquals(Utils.newArrayList("c", "d"), pojo.getStrList());
  125. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  126. beginTxn();
  127. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  128. // reattach to the pm - this turns our regular list field into a managed
  129. // list field
  130. pojo = pm.makePersistent(pojo);
  131. assertEquals(ObjectState.PERSISTENT_CLEAN, JDOHelper.getObjectState(pojo));
  132. pojo.getStrList().add("e");
  133. commitTxn();
  134. Entity e = ds.get(KeyFactory.createKey(DetachableWithMultiValuePropsJDO.class.getSimpleName(), pojo.getId()));
  135. assertEquals(3, ((List<String>)e.getProperty("strList")).size());
  136. assertEquals(Utils.newArrayList("c", "d", "e"), e.getProperty("strList"));
  137. }
  138. public void testSerializeWithOneToMany_AddBidirectionalChildToDetached() throws Exception {
  139. pm.setDetachAllOnCommit(true);
  140. beginTxn();
  141. HasOneToManyListJDO pojo = new HasOneToManyListJDO();
  142. pojo.setVal("yar");
  143. BidirectionalChildListJDO bidir = new BidirectionalChildListJDO();
  144. bidir.setChildVal("yar2");
  145. pojo.addBidirChild(bidir);
  146. pm.makePersistent(pojo);
  147. commitTxn();
  148. pm.close();
  149. pm = pmf.getPersistenceManager();
  150. pojo = toBytesAndBack(pojo);
  151. assertEquals("yar", pojo.getVal());
  152. assertEquals(1, pojo.getBidirChildren().size());
  153. BidirectionalChildListJDO bidir2 = new BidirectionalChildListJDO();
  154. bidir2.setChildVal("yar3");
  155. pojo.addBidirChild(bidir2);
  156. bidir2.setParent(pojo);
  157. beginTxn();
  158. pojo = pm.makePersistent(pojo);
  159. commitTxn();
  160. Entity e = ds.get(KeyFactory.stringToKey(bidir2.getId()));
  161. assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
  162. }
  163. public void testSerializeWithOneToMany_AddUnidirectionalChildToDetached() throws Exception {
  164. pm.setDetachAllOnCommit(true);
  165. beginTxn();
  166. HasOneToManyListJDO pojo = new HasOneToManyListJDO();
  167. pojo.setVal("yar");
  168. Flight flight = new Flight();
  169. flight.setName("harry");
  170. pojo.addFlight(flight);
  171. pm.makePersistent(pojo);
  172. commitTxn();
  173. pm.close();
  174. pm = pmf.getPersistenceManager();
  175. pojo = toBytesAndBack(pojo);
  176. assertEquals("yar", pojo.getVal());
  177. assertEquals(1, pojo.getFlights().size());
  178. Flight flight2 = new Flight();
  179. flight2.setName("not harry");
  180. pojo.addFlight(flight2);
  181. beginTxn();
  182. pojo = pm.makePersistent(pojo);
  183. commitTxn();
  184. Entity e = ds.get(KeyFactory.stringToKey(flight2.getId()));
  185. assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
  186. }
  187. public void testSerializeWithOneToMany_AddChildToReattached() throws Exception {
  188. pm.setDetachAllOnCommit(true);
  189. beginTxn();
  190. HasOneToManyListJDO pojo = new HasOneToManyListJDO();
  191. pojo.setVal("yar");
  192. BidirectionalChildListJDO bidir = new BidirectionalChildListJDO();
  193. bidir.setChildVal("yar2");
  194. pojo.addBidirChild(bidir);
  195. pm.makePersistent(pojo);
  196. commitTxn();
  197. pm.close();
  198. pm = pmf.getPersistenceManager();
  199. pojo = toBytesAndBack(pojo);
  200. assertEquals("yar", pojo.getVal());
  201. assertEquals(1, pojo.getBidirChildren().size());
  202. beginTxn();
  203. pojo = pm.makePersistent(pojo);
  204. BidirectionalChildListJDO bidir2 = new BidirectionalChildListJDO();
  205. bidir.setChildVal("yar3");
  206. pojo.addBidirChild(bidir2);
  207. bidir2.setParent(pojo);
  208. commitTxn();
  209. Entity e = ds.get(KeyFactory.stringToKey(bidir2.getId()));
  210. assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
  211. }
  212. public void testDeleteDetachedObject_NoTxn() {
  213. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  214. DetachableJDO pojo = new DetachableJDO();
  215. pojo.setVal("yar");
  216. Date now = new Date();
  217. pojo.setDate(now);
  218. pm.makePersistent(pojo);
  219. pm.close();
  220. pm = pmf.getPersistenceManager();
  221. pojo = pm.detachCopy(pm.getObjectById(pojo.getClass(), pojo.getId()));
  222. pm.close();
  223. pm = pmf.getPersistenceManager();
  224. pm.deletePersistent(pojo);
  225. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  226. pm.close();
  227. pm = pmf.getPersistenceManager();
  228. try {
  229. pm.getObjectById(pojo.getClass(), pojo.getId());
  230. fail("expected exception");
  231. } catch (JDOObjectNotFoundException e) {
  232. // good
  233. }
  234. }
  235. public void testDeleteDetachedNewObject_NoTxn() {
  236. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  237. DetachableJDO pojo = new DetachableJDO();
  238. pojo.setVal("yar");
  239. Date now = new Date();
  240. pojo.setDate(now);
  241. pm.makePersistent(pojo);
  242. pojo = pm.detachCopy(pojo);
  243. pm.close();
  244. pm = pmf.getPersistenceManager();
  245. pm.deletePersistent(pojo);
  246. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  247. pm.close();
  248. pm = pmf.getPersistenceManager();
  249. try {
  250. pm.getObjectById(pojo.getClass(), pojo.getId());
  251. fail("expected exception");
  252. } catch (JDOObjectNotFoundException e) {
  253. // good
  254. }
  255. }
  256. public void testDeleteDetachedObject_Txn() {
  257. beginTxn();
  258. DetachableJDO pojo = new DetachableJDO();
  259. pojo.setVal("yar");
  260. Date now = new Date();
  261. pojo.setDate(now);
  262. pm.makePersistent(pojo);
  263. commitTxn();
  264. beginTxn();
  265. pojo = pm.detachCopy(pm.getObjectById(pojo.getClass(), pojo.getId()));
  266. commitTxn();
  267. beginTxn();
  268. pm.deletePersistent(pojo);
  269. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  270. commitTxn();
  271. beginTxn();
  272. try {
  273. pm.getObjectById(pojo.getClass(), pojo.getId());
  274. fail("expected exception");
  275. } catch (JDOObjectNotFoundException e) {
  276. // good
  277. }
  278. rollbackTxn();
  279. }
  280. public void testDeleteDetachedNewObject_Txn() {
  281. beginTxn();
  282. DetachableJDO pojo = new DetachableJDO();
  283. pojo.setVal("yar");
  284. Date now = new Date();
  285. pojo.setDate(now);
  286. pm.makePersistent(pojo);
  287. pojo = pm.detachCopy(pojo);
  288. commitTxn();
  289. beginTxn();
  290. pm.deletePersistent(pojo);
  291. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  292. commitTxn();
  293. beginTxn();
  294. try {
  295. pm.getObjectById(pojo.getClass(), pojo.getId());
  296. fail("expected exception");
  297. } catch (JDOObjectNotFoundException e) {
  298. // good
  299. }
  300. rollbackTxn();
  301. }
  302. }