PageRenderTime 34ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/com/google/appengine/datanucleus/jpa/JPAAttachDetachTest.java

http://datanucleus-appengine.googlecode.com/
Java | 341 lines | 269 code | 29 blank | 43 comment | 0 complexity | 8bf325735944752ff2b5293bc6055b64 MD5 | raw file
Possible License(s): Apache-2.0
  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.jpa;
  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.DetachableWithMultiValuePropsJDO;
  23. import com.google.appengine.datanucleus.test.jpa.BidirectionalChildListJPA;
  24. import com.google.appengine.datanucleus.test.jpa.Book;
  25. import com.google.appengine.datanucleus.test.jpa.DetachableJPA;
  26. import com.google.appengine.datanucleus.test.jpa.HasGrandchildJPA;
  27. import com.google.appengine.datanucleus.test.jpa.HasOneToManyListJPA;
  28. import com.google.appengine.datanucleus.test.jpa.HasOneToManySetJPA;
  29. import java.io.ByteArrayInputStream;
  30. import java.io.ByteArrayOutputStream;
  31. import java.io.IOException;
  32. import java.io.ObjectInputStream;
  33. import java.io.ObjectOutputStream;
  34. import java.io.Serializable;
  35. import java.util.Date;
  36. import java.util.List;
  37. import javax.jdo.JDOHelper;
  38. import javax.jdo.ObjectState;
  39. /**
  40. * @author Max Ross <maxr@google.com>
  41. */
  42. public class JPAAttachDetachTest extends JPATestCase {
  43. private <T extends Serializable> T toBytesAndBack(T obj)
  44. throws IOException, ClassNotFoundException {
  45. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  46. ObjectOutputStream oos = new ObjectOutputStream(baos);
  47. oos.writeObject(obj);
  48. ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  49. ObjectInputStream ois = new ObjectInputStream(bais);
  50. return (T) ois.readObject();
  51. }
  52. public void testSimpleSerializeWithTxns()
  53. throws IOException, ClassNotFoundException, EntityNotFoundException {
  54. beginTxn();
  55. DetachableJPA pojo = new DetachableJPA();
  56. pojo.setVal("yar");
  57. Date now = new Date();
  58. pojo.setDate(now);
  59. em.persist(pojo);
  60. commitTxn();
  61. assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
  62. assertTrue(Date.class.isAssignableFrom(pojo.getDate().getClass()));
  63. em.close(); // Detaches objects in L1 cache
  64. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  65. em = emf.createEntityManager();
  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 differentNow = new Date(now.getTime() + 1);
  75. pojo.setDate(differentNow);
  76. assertEquals(ObjectState.DETACHED_DIRTY, JDOHelper.getObjectState(pojo));
  77. pojo = em.merge(pojo);
  78. assertEquals(ObjectState.PERSISTENT_DIRTY, JDOHelper.getObjectState(pojo));
  79. commitTxn();
  80. assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
  81. Entity e = ds.get(KeyFactory.createKey(DetachableJPA.class.getSimpleName(), pojo.getId()));
  82. assertEquals("not yar", e.getProperty("val"));
  83. assertEquals(differentNow, e.getProperty("date"));
  84. }
  85. public void testSimpleSerializeWithoutTxns() throws Exception {
  86. switchDatasource(EntityManagerFactoryName.nontransactional_ds_non_transactional_ops_allowed);
  87. DetachableJPA pojo = new DetachableJPA();
  88. pojo.setVal("yar");
  89. Date now = new Date();
  90. pojo.setDate(now);
  91. em.persist(pojo);
  92. assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
  93. em.close(); // Detaches objects in L1 cache
  94. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  95. assertEquals(Date.class, pojo.getDate().getClass());
  96. em = emf.createEntityManager();
  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 differentNow = new Date(now.getTime() + 1);
  103. pojo.setDate(differentNow);
  104. assertEquals(ObjectState.DETACHED_DIRTY, JDOHelper.getObjectState(pojo));
  105. em.merge(pojo);
  106. em.close(); // Detaches objects in L1 cache
  107. Entity e = ds.get(KeyFactory.createKey(DetachableJPA.class.getSimpleName(), pojo.getId()));
  108. assertEquals("not yar", e.getProperty("val"));
  109. assertEquals(differentNow, e.getProperty("date"));
  110. }
  111. public void testMergeAfterFetch() throws Exception {
  112. switchDatasource(EntityManagerFactoryName.nontransactional_ds_non_transactional_ops_allowed);
  113. DetachableJPA pojo = new DetachableJPA();
  114. pojo.setVal("yar");
  115. Date now = new Date();
  116. pojo.setDate(now);
  117. em.persist(pojo);
  118. em.close();
  119. em = emf.createEntityManager();
  120. // beginTxn();
  121. // pojo = em.find(DetachableJPA.class, pojo.getId());
  122. pojo = (DetachableJPA) em.createQuery("select from " + DetachableJPA.class.getName() + " b").getSingleResult();
  123. // commitTxn();
  124. em.close();
  125. em = emf.createEntityManager();
  126. assertEquals("yar", pojo.getVal());
  127. pojo.setVal("not yar");
  128. em.merge(pojo);
  129. em.close();
  130. Entity e = ds.get(KeyFactory.createKey(DetachableJPA.class.getSimpleName(), pojo.getId()));
  131. assertEquals("not yar", e.getProperty("val"));
  132. }
  133. // TODO Should not be referring to DetachableWithMultiValuePropsJDO since is JDO!!
  134. public void testSerializeWithMultiValueProps() throws Exception {
  135. beginTxn();
  136. DetachableWithMultiValuePropsJDO pojo = new DetachableWithMultiValuePropsJDO();
  137. pojo.setStrList(Utils.newArrayList("c", "d"));
  138. em.persist(pojo);
  139. commitTxn();
  140. assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
  141. em.close(); // Detaches objects in L1 cache
  142. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  143. em = emf.createEntityManager();
  144. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  145. pojo = toBytesAndBack(pojo);
  146. assertEquals(Utils.newArrayList("c", "d"), pojo.getStrList());
  147. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  148. beginTxn();
  149. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  150. // reattach to the pm - this turns our regular list field into a managed
  151. // list field
  152. pojo = em.merge(pojo);
  153. assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
  154. pojo.getStrList().add("e");
  155. commitTxn();
  156. Entity e = ds.get(KeyFactory.createKey(DetachableWithMultiValuePropsJDO.class.getSimpleName(), pojo.getId()));
  157. assertEquals(3, ((List<String>)e.getProperty("strList")).size());
  158. assertEquals(Utils.newArrayList("c", "d", "e"), e.getProperty("strList"));
  159. }
  160. public void testSerializeWithOneToMany_AddChildToBidirectionalDetached() throws Exception {
  161. beginTxn();
  162. HasOneToManyListJPA pojo = new HasOneToManyListJPA();
  163. pojo.setVal("yar");
  164. BidirectionalChildListJPA bidir = new BidirectionalChildListJPA();
  165. bidir.setChildVal("yar2");
  166. pojo.getBidirChildren().add(bidir);
  167. em.persist(pojo);
  168. commitTxn();
  169. em.close();
  170. em = emf.createEntityManager();
  171. pojo = toBytesAndBack(pojo);
  172. assertEquals("yar", pojo.getVal());
  173. assertEquals(1, pojo.getBidirChildren().size());
  174. BidirectionalChildListJPA bidir2 = new BidirectionalChildListJPA();
  175. bidir.setChildVal("yar3");
  176. pojo.getBidirChildren().add(bidir2);
  177. // Don't set the parent - this ref won't get updated when we call
  178. // merge and we'll get an exception.
  179. // bidir2.setParent(pojo);
  180. beginTxn();
  181. pojo = em.merge(pojo);
  182. commitTxn();
  183. Entity e = ds.get(KeyFactory.stringToKey(bidir2.getId()));
  184. assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
  185. }
  186. public void testSerializeWithOneToMany_AddChildToUnidirectionalDetached() throws Exception {
  187. beginTxn();
  188. HasOneToManyListJPA pojo = new HasOneToManyListJPA();
  189. pojo.setVal("yar");
  190. Book b = new Book();
  191. b.setAuthor("harry");
  192. pojo.getBooks().add(b);
  193. em.persist(pojo);
  194. commitTxn();
  195. em.close();
  196. em = emf.createEntityManager();
  197. pojo = toBytesAndBack(pojo);
  198. assertEquals("yar", pojo.getVal());
  199. assertEquals(1, pojo.getBooks().size());
  200. Book b2 = new Book();
  201. b2.setAuthor("yar3");
  202. pojo.getBooks().add(b2);
  203. // Don't set the parent - this ref won't get updated when we call
  204. // merge and we'll get an exception.
  205. // bidir2.setParent(pojo);
  206. beginTxn();
  207. pojo = em.merge(pojo);
  208. commitTxn();
  209. Entity e = ds.get(KeyFactory.stringToKey(b2.getId()));
  210. assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
  211. }
  212. public void testSerializeWithOneToMany_AddGrandchildToUnidirectionalDetached() throws Exception {
  213. beginTxn();
  214. HasGrandchildJPA hasGrandchild = new HasGrandchildJPA();
  215. HasOneToManySetJPA pojo = new HasOneToManySetJPA();
  216. hasGrandchild.getYar().add(pojo);
  217. pojo.setVal("yar");
  218. Book b = new Book();
  219. b.setAuthor("harry");
  220. pojo.getBooks().add(b);
  221. em.persist(hasGrandchild);
  222. commitTxn();
  223. em.close();
  224. em = emf.createEntityManager();
  225. hasGrandchild = toBytesAndBack(hasGrandchild);
  226. pojo = hasGrandchild.getYar().iterator().next();
  227. assertEquals("yar", pojo.getVal());
  228. assertEquals(1, pojo.getBooks().size());
  229. Book b2 = new Book();
  230. b2.setAuthor("yar3");
  231. pojo.getBooks().add(b2);
  232. // Don't set the parent - this ref won't get updated when we call
  233. // merge and we'll get an exception.
  234. // bidir2.setParent(pojo);
  235. beginTxn();
  236. hasGrandchild = em.merge(hasGrandchild);
  237. commitTxn();
  238. Entity e = ds.get(KeyFactory.stringToKey(b2.getId()));
  239. assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
  240. }
  241. public void testSerializeWithOneToMany_AddChildToReattached() throws Exception {
  242. beginTxn();
  243. HasOneToManyListJPA pojo = new HasOneToManyListJPA();
  244. pojo.setVal("yar");
  245. BidirectionalChildListJPA bidir = new BidirectionalChildListJPA();
  246. bidir.setChildVal("yar2");
  247. pojo.getBidirChildren().add(bidir);
  248. em.persist(pojo);
  249. commitTxn();
  250. em.close();
  251. em = emf.createEntityManager();
  252. pojo = toBytesAndBack(pojo);
  253. assertEquals("yar", pojo.getVal());
  254. assertEquals(1, pojo.getBidirChildren().size());
  255. beginTxn();
  256. pojo = em.merge(pojo);
  257. BidirectionalChildListJPA bidir2 = new BidirectionalChildListJPA();
  258. bidir.setChildVal("yar3");
  259. pojo.getBidirChildren().add(bidir2);
  260. bidir2.setParent(pojo);
  261. commitTxn();
  262. Entity e = ds.get(KeyFactory.stringToKey(bidir2.getId()));
  263. assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
  264. }
  265. public void testDeleteDetachedObject_NoTxn() {
  266. switchDatasource(EntityManagerFactoryName.nontransactional_ds_non_transactional_ops_not_allowed);
  267. DetachableJPA pojo = new DetachableJPA();
  268. pojo.setVal("yar");
  269. Date now = new Date();
  270. pojo.setDate(now);
  271. em.persist(pojo);
  272. em.close(); // Detaches objects in L1 cache
  273. assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
  274. em = emf.createEntityManager();
  275. pojo = em.find(pojo.getClass(), pojo.getId());
  276. assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
  277. em.close();
  278. em = emf.createEntityManager();
  279. pojo = em.merge(pojo);
  280. // this is wrong and it will start to fail when we upgrade to DN 2.0
  281. // We're tracking this with bug
  282. // http://code.google.com/p/datanucleus-appengine/issues/detail?id=142
  283. assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
  284. // assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
  285. // em.remove(pojo);
  286. // assertEquals(ObjectState.PERSISTENT_NEW_DELETED, JDOHelper.getObjectState(pojo));
  287. // em.close();
  288. // em = emf.createEntityManager();
  289. // assertNull(em.find(pojo.getClass(), pojo.getId()));
  290. }
  291. public void testDeleteDetachedObject_Txn() {
  292. beginTxn();
  293. DetachableJPA pojo = new DetachableJPA();
  294. pojo.setVal("yar");
  295. Date now = new Date();
  296. pojo.setDate(now);
  297. em.persist(pojo);
  298. commitTxn();
  299. Long id = pojo.getId();
  300. beginTxn();
  301. pojo = em.find(pojo.getClass(), pojo.getId());
  302. commitTxn();
  303. beginTxn();
  304. pojo = em.merge(pojo);
  305. em.remove(pojo);
  306. assertEquals(ObjectState.PERSISTENT_DELETED, JDOHelper.getObjectState(pojo));
  307. commitTxn();
  308. beginTxn();
  309. assertNull(em.find(pojo.getClass(), id));
  310. rollbackTxn();
  311. }
  312. }