/tests/com/google/appengine/datanucleus/jpa/JPAAttachDetachTest.java
Java | 341 lines | 269 code | 29 blank | 43 comment | 0 complexity | 8bf325735944752ff2b5293bc6055b64 MD5 | raw file
Possible License(s): Apache-2.0
- /*
- * /**********************************************************************
- * Copyright (c) 2009 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * **********************************************************************/
- package com.google.appengine.datanucleus.jpa;
- import com.google.appengine.api.datastore.Entity;
- import com.google.appengine.api.datastore.EntityNotFoundException;
- import com.google.appengine.api.datastore.KeyFactory;
- import com.google.appengine.datanucleus.Utils;
- import com.google.appengine.datanucleus.test.jdo.DetachableWithMultiValuePropsJDO;
- import com.google.appengine.datanucleus.test.jpa.BidirectionalChildListJPA;
- import com.google.appengine.datanucleus.test.jpa.Book;
- import com.google.appengine.datanucleus.test.jpa.DetachableJPA;
- import com.google.appengine.datanucleus.test.jpa.HasGrandchildJPA;
- import com.google.appengine.datanucleus.test.jpa.HasOneToManyListJPA;
- import com.google.appengine.datanucleus.test.jpa.HasOneToManySetJPA;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.io.Serializable;
- import java.util.Date;
- import java.util.List;
- import javax.jdo.JDOHelper;
- import javax.jdo.ObjectState;
- /**
- * @author Max Ross <maxr@google.com>
- */
- public class JPAAttachDetachTest extends JPATestCase {
- private <T extends Serializable> T toBytesAndBack(T obj)
- throws IOException, ClassNotFoundException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(obj);
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bais);
- return (T) ois.readObject();
- }
- public void testSimpleSerializeWithTxns()
- throws IOException, ClassNotFoundException, EntityNotFoundException {
- beginTxn();
- DetachableJPA pojo = new DetachableJPA();
- pojo.setVal("yar");
- Date now = new Date();
- pojo.setDate(now);
- em.persist(pojo);
- commitTxn();
- assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
- assertTrue(Date.class.isAssignableFrom(pojo.getDate().getClass()));
- em.close(); // Detaches objects in L1 cache
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- em = emf.createEntityManager();
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- pojo = toBytesAndBack(pojo);
- assertEquals("yar", pojo.getVal());
- assertEquals(now, pojo.getDate());
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- beginTxn();
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- pojo.setVal("not yar");
- Date differentNow = new Date(now.getTime() + 1);
- pojo.setDate(differentNow);
- assertEquals(ObjectState.DETACHED_DIRTY, JDOHelper.getObjectState(pojo));
- pojo = em.merge(pojo);
- assertEquals(ObjectState.PERSISTENT_DIRTY, JDOHelper.getObjectState(pojo));
- commitTxn();
- assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
- Entity e = ds.get(KeyFactory.createKey(DetachableJPA.class.getSimpleName(), pojo.getId()));
- assertEquals("not yar", e.getProperty("val"));
- assertEquals(differentNow, e.getProperty("date"));
- }
- public void testSimpleSerializeWithoutTxns() throws Exception {
- switchDatasource(EntityManagerFactoryName.nontransactional_ds_non_transactional_ops_allowed);
- DetachableJPA pojo = new DetachableJPA();
- pojo.setVal("yar");
- Date now = new Date();
- pojo.setDate(now);
- em.persist(pojo);
- assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
- em.close(); // Detaches objects in L1 cache
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- assertEquals(Date.class, pojo.getDate().getClass());
- em = emf.createEntityManager();
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- pojo = toBytesAndBack(pojo);
- assertEquals("yar", pojo.getVal());
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- pojo.setVal("not yar");
- Date differentNow = new Date(now.getTime() + 1);
- pojo.setDate(differentNow);
- assertEquals(ObjectState.DETACHED_DIRTY, JDOHelper.getObjectState(pojo));
- em.merge(pojo);
- em.close(); // Detaches objects in L1 cache
- Entity e = ds.get(KeyFactory.createKey(DetachableJPA.class.getSimpleName(), pojo.getId()));
- assertEquals("not yar", e.getProperty("val"));
- assertEquals(differentNow, e.getProperty("date"));
- }
- public void testMergeAfterFetch() throws Exception {
- switchDatasource(EntityManagerFactoryName.nontransactional_ds_non_transactional_ops_allowed);
- DetachableJPA pojo = new DetachableJPA();
- pojo.setVal("yar");
- Date now = new Date();
- pojo.setDate(now);
- em.persist(pojo);
- em.close();
- em = emf.createEntityManager();
- // beginTxn();
- // pojo = em.find(DetachableJPA.class, pojo.getId());
- pojo = (DetachableJPA) em.createQuery("select from " + DetachableJPA.class.getName() + " b").getSingleResult();
- // commitTxn();
- em.close();
- em = emf.createEntityManager();
- assertEquals("yar", pojo.getVal());
- pojo.setVal("not yar");
- em.merge(pojo);
- em.close();
- Entity e = ds.get(KeyFactory.createKey(DetachableJPA.class.getSimpleName(), pojo.getId()));
- assertEquals("not yar", e.getProperty("val"));
- }
- // TODO Should not be referring to DetachableWithMultiValuePropsJDO since is JDO!!
- public void testSerializeWithMultiValueProps() throws Exception {
- beginTxn();
- DetachableWithMultiValuePropsJDO pojo = new DetachableWithMultiValuePropsJDO();
- pojo.setStrList(Utils.newArrayList("c", "d"));
- em.persist(pojo);
- commitTxn();
- assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
- em.close(); // Detaches objects in L1 cache
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- em = emf.createEntityManager();
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- pojo = toBytesAndBack(pojo);
- assertEquals(Utils.newArrayList("c", "d"), pojo.getStrList());
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- beginTxn();
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- // reattach to the pm - this turns our regular list field into a managed
- // list field
- pojo = em.merge(pojo);
- assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
- pojo.getStrList().add("e");
- commitTxn();
- Entity e = ds.get(KeyFactory.createKey(DetachableWithMultiValuePropsJDO.class.getSimpleName(), pojo.getId()));
- assertEquals(3, ((List<String>)e.getProperty("strList")).size());
- assertEquals(Utils.newArrayList("c", "d", "e"), e.getProperty("strList"));
- }
- public void testSerializeWithOneToMany_AddChildToBidirectionalDetached() throws Exception {
- beginTxn();
- HasOneToManyListJPA pojo = new HasOneToManyListJPA();
- pojo.setVal("yar");
- BidirectionalChildListJPA bidir = new BidirectionalChildListJPA();
- bidir.setChildVal("yar2");
- pojo.getBidirChildren().add(bidir);
- em.persist(pojo);
- commitTxn();
- em.close();
- em = emf.createEntityManager();
- pojo = toBytesAndBack(pojo);
- assertEquals("yar", pojo.getVal());
- assertEquals(1, pojo.getBidirChildren().size());
- BidirectionalChildListJPA bidir2 = new BidirectionalChildListJPA();
- bidir.setChildVal("yar3");
- pojo.getBidirChildren().add(bidir2);
- // Don't set the parent - this ref won't get updated when we call
- // merge and we'll get an exception.
- // bidir2.setParent(pojo);
- beginTxn();
- pojo = em.merge(pojo);
- commitTxn();
- Entity e = ds.get(KeyFactory.stringToKey(bidir2.getId()));
- assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
- }
- public void testSerializeWithOneToMany_AddChildToUnidirectionalDetached() throws Exception {
- beginTxn();
- HasOneToManyListJPA pojo = new HasOneToManyListJPA();
- pojo.setVal("yar");
- Book b = new Book();
- b.setAuthor("harry");
- pojo.getBooks().add(b);
- em.persist(pojo);
- commitTxn();
- em.close();
- em = emf.createEntityManager();
- pojo = toBytesAndBack(pojo);
- assertEquals("yar", pojo.getVal());
- assertEquals(1, pojo.getBooks().size());
- Book b2 = new Book();
- b2.setAuthor("yar3");
- pojo.getBooks().add(b2);
- // Don't set the parent - this ref won't get updated when we call
- // merge and we'll get an exception.
- // bidir2.setParent(pojo);
- beginTxn();
- pojo = em.merge(pojo);
- commitTxn();
- Entity e = ds.get(KeyFactory.stringToKey(b2.getId()));
- assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
- }
- public void testSerializeWithOneToMany_AddGrandchildToUnidirectionalDetached() throws Exception {
- beginTxn();
- HasGrandchildJPA hasGrandchild = new HasGrandchildJPA();
- HasOneToManySetJPA pojo = new HasOneToManySetJPA();
- hasGrandchild.getYar().add(pojo);
- pojo.setVal("yar");
- Book b = new Book();
- b.setAuthor("harry");
- pojo.getBooks().add(b);
- em.persist(hasGrandchild);
- commitTxn();
- em.close();
- em = emf.createEntityManager();
- hasGrandchild = toBytesAndBack(hasGrandchild);
- pojo = hasGrandchild.getYar().iterator().next();
- assertEquals("yar", pojo.getVal());
- assertEquals(1, pojo.getBooks().size());
- Book b2 = new Book();
- b2.setAuthor("yar3");
- pojo.getBooks().add(b2);
- // Don't set the parent - this ref won't get updated when we call
- // merge and we'll get an exception.
- // bidir2.setParent(pojo);
- beginTxn();
- hasGrandchild = em.merge(hasGrandchild);
- commitTxn();
- Entity e = ds.get(KeyFactory.stringToKey(b2.getId()));
- assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
- }
- public void testSerializeWithOneToMany_AddChildToReattached() throws Exception {
- beginTxn();
- HasOneToManyListJPA pojo = new HasOneToManyListJPA();
- pojo.setVal("yar");
- BidirectionalChildListJPA bidir = new BidirectionalChildListJPA();
- bidir.setChildVal("yar2");
- pojo.getBidirChildren().add(bidir);
- em.persist(pojo);
- commitTxn();
- em.close();
- em = emf.createEntityManager();
- pojo = toBytesAndBack(pojo);
- assertEquals("yar", pojo.getVal());
- assertEquals(1, pojo.getBidirChildren().size());
- beginTxn();
- pojo = em.merge(pojo);
- BidirectionalChildListJPA bidir2 = new BidirectionalChildListJPA();
- bidir.setChildVal("yar3");
- pojo.getBidirChildren().add(bidir2);
- bidir2.setParent(pojo);
- commitTxn();
- Entity e = ds.get(KeyFactory.stringToKey(bidir2.getId()));
- assertEquals(KeyFactory.stringToKey(pojo.getId()), e.getKey().getParent());
- }
-
- public void testDeleteDetachedObject_NoTxn() {
- switchDatasource(EntityManagerFactoryName.nontransactional_ds_non_transactional_ops_not_allowed);
- DetachableJPA pojo = new DetachableJPA();
- pojo.setVal("yar");
- Date now = new Date();
- pojo.setDate(now);
- em.persist(pojo);
- em.close(); // Detaches objects in L1 cache
- assertEquals(ObjectState.DETACHED_CLEAN, JDOHelper.getObjectState(pojo));
- em = emf.createEntityManager();
- pojo = em.find(pojo.getClass(), pojo.getId());
- assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
- em.close();
- em = emf.createEntityManager();
- pojo = em.merge(pojo);
- // this is wrong and it will start to fail when we upgrade to DN 2.0
- // We're tracking this with bug
- // http://code.google.com/p/datanucleus-appengine/issues/detail?id=142
- assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
- // assertEquals(ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL, JDOHelper.getObjectState(pojo));
- // em.remove(pojo);
- // assertEquals(ObjectState.PERSISTENT_NEW_DELETED, JDOHelper.getObjectState(pojo));
- // em.close();
- // em = emf.createEntityManager();
- // assertNull(em.find(pojo.getClass(), pojo.getId()));
- }
-
- public void testDeleteDetachedObject_Txn() {
- beginTxn();
- DetachableJPA pojo = new DetachableJPA();
- pojo.setVal("yar");
- Date now = new Date();
- pojo.setDate(now);
- em.persist(pojo);
- commitTxn();
- Long id = pojo.getId();
- beginTxn();
- pojo = em.find(pojo.getClass(), pojo.getId());
- commitTxn();
- beginTxn();
- pojo = em.merge(pojo);
- em.remove(pojo);
- assertEquals(ObjectState.PERSISTENT_DELETED, JDOHelper.getObjectState(pojo));
- commitTxn();
- beginTxn();
- assertNull(em.find(pojo.getClass(), id));
- rollbackTxn();
- }
- }