Home | History | Annotate | Download | only in jpa
      1 /**
      2  * Copyright (C) 2010 Google, Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.inject.persist.jpa;
     18 
     19 import com.google.inject.Guice;
     20 import com.google.inject.Inject;
     21 import com.google.inject.Injector;
     22 import com.google.inject.persist.PersistService;
     23 import com.google.inject.persist.Transactional;
     24 import com.google.inject.persist.UnitOfWork;
     25 
     26 import junit.framework.TestCase;
     27 
     28 import java.io.IOException;
     29 import java.util.Date;
     30 
     31 import javax.persistence.EntityManager;
     32 import javax.persistence.EntityManagerFactory;
     33 import javax.persistence.NoResultException;
     34 
     35 /**
     36  * @author Dhanji R. Prasanna (dhanji (at) gmail.com)
     37  */
     38 
     39 public class ManagedLocalTransactionsTest extends TestCase {
     40   private Injector injector;
     41   private static final String UNIQUE_TEXT = "some unique text" + new Date();
     42   private static final String UNIQUE_TEXT_MERGE = "meRG_Esome unique text" + new Date();
     43   private static final String TRANSIENT_UNIQUE_TEXT = "some other unique text" + new Date();
     44 
     45   @Override
     46   public void setUp() {
     47     injector = Guice.createInjector(new JpaPersistModule("testUnit"));
     48 
     49     //startup persistence
     50     injector.getInstance(PersistService.class).start();
     51   }
     52 
     53   @Override
     54   public final void tearDown() {
     55     injector.getInstance(UnitOfWork.class).end();
     56     injector.getInstance(EntityManagerFactory.class).close();
     57   }
     58 
     59   public void testSimpleTransaction() {
     60     injector.getInstance(TransactionalObject.class).runOperationInTxn();
     61 
     62     EntityManager em = injector.getInstance(EntityManager.class);
     63     assertFalse("txn was not closed by transactional service", em.getTransaction().isActive());
     64 
     65     //test that the data has been stored
     66     Object result = em.createQuery("from JpaTestEntity where text = :text")
     67         .setParameter("text", UNIQUE_TEXT).getSingleResult();
     68     injector.getInstance(UnitOfWork.class).end();
     69 
     70     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);
     71 
     72     assertEquals("queried entity did not match--did automatic txn fail?",
     73         UNIQUE_TEXT, ((JpaTestEntity) result).getText());
     74   }
     75 
     76   public void testSimpleTransactionWithMerge() {
     77     JpaTestEntity entity = injector.getInstance(TransactionalObject.class)
     78         .runOperationInTxnWithMerge();
     79 
     80     EntityManager em = injector.getInstance(EntityManager.class);
     81     assertFalse("txn was not closed by transactional service", em.getTransaction().isActive());
     82 
     83     //test that the data has been stored
     84     assertTrue("Em was closed after txn!", em.isOpen());
     85 
     86     Object result = em.createQuery("from JpaTestEntity where text = :text")
     87         .setParameter("text", UNIQUE_TEXT_MERGE).getSingleResult();
     88     injector.getInstance(UnitOfWork.class).end();
     89 
     90     assertTrue(result instanceof JpaTestEntity);
     91 
     92     assertEquals("queried entity did not match--did automatic txn fail?",
     93         UNIQUE_TEXT_MERGE, ((JpaTestEntity) result).getText());
     94   }
     95 
     96   public void testSimpleTransactionRollbackOnChecked() {
     97     try {
     98       injector.getInstance(TransactionalObject.class).runOperationInTxnThrowingChecked();
     99     } catch (IOException e) {
    100       //ignore
    101       injector.getInstance(UnitOfWork.class).end();
    102     }
    103 
    104     EntityManager em = injector.getInstance(EntityManager.class);
    105 
    106     assertFalse("Previous EM was not closed by transactional service (rollback didnt happen?)",
    107         em.getTransaction().isActive());
    108 
    109     //test that the data has been stored
    110     try {
    111       Object result = em.createQuery("from JpaTestEntity where text = :text")
    112           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
    113       injector.getInstance(UnitOfWork.class).end();
    114       fail("a result was returned! rollback sure didnt happen!!!");
    115     } catch (NoResultException e) {}
    116   }
    117 
    118   public void testSimpleTransactionRollbackOnUnchecked() {
    119     try {
    120       injector.getInstance(TransactionalObject.class).runOperationInTxnThrowingUnchecked();
    121     } catch (RuntimeException re) {
    122       //ignore
    123       injector.getInstance(UnitOfWork.class).end();
    124     }
    125 
    126     EntityManager em = injector.getInstance(EntityManager.class);
    127     assertFalse("Session was not closed by transactional service (rollback didnt happen?)",
    128         em.getTransaction().isActive());
    129 
    130     try {
    131       Object result = em.createQuery("from JpaTestEntity where text = :text")
    132           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
    133       injector.getInstance(UnitOfWork.class).end();
    134       fail("a result was returned! rollback sure didnt happen!!!");
    135     } catch (NoResultException e) {}
    136   }
    137 
    138   public static class TransactionalObject {
    139     private final EntityManager em;
    140 
    141     @Inject
    142     public TransactionalObject(EntityManager em) {
    143       this.em = em;
    144     }
    145 
    146     @Transactional
    147     public void runOperationInTxn() {
    148       JpaTestEntity entity = new JpaTestEntity();
    149       entity.setText(UNIQUE_TEXT);
    150       em.persist(entity);
    151     }
    152 
    153     @Transactional
    154     public JpaTestEntity runOperationInTxnWithMerge() {
    155       JpaTestEntity entity = new JpaTestEntity();
    156       entity.setText(UNIQUE_TEXT_MERGE);
    157       return em.merge(entity);
    158     }
    159 
    160     @Transactional(rollbackOn = IOException.class)
    161     public void runOperationInTxnThrowingChecked() throws IOException {
    162       JpaTestEntity entity = new JpaTestEntity();
    163       entity.setText(TRANSIENT_UNIQUE_TEXT);
    164       em.persist(entity);
    165 
    166       throw new IOException();
    167     }
    168 
    169     @Transactional
    170     public void runOperationInTxnThrowingUnchecked() {
    171       JpaTestEntity entity = new JpaTestEntity();
    172       entity.setText(TRANSIENT_UNIQUE_TEXT);
    173       em.persist(entity);
    174 
    175       throw new IllegalStateException();
    176     }
    177   }
    178 }
    179