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 JoiningLocalTransactionsTest extends TestCase {
     40   private Injector injector;
     41   private static final String UNIQUE_TEXT = JoiningLocalTransactionsTest.class + "some unique text"
     42       + new Date();
     43   private static final String TRANSIENT_UNIQUE_TEXT = JoiningLocalTransactionsTest.class
     44       + "some other unique text" + new Date();
     45 
     46   @Override
     47   public void setUp() {
     48     injector = Guice.createInjector(new JpaPersistModule("testUnit"));
     49 
     50     //startup persistence
     51     injector.getInstance(PersistService.class).start();
     52   }
     53 
     54   //cleanup entitymanager in case some of the rollback tests left it in an open state
     55   @Override
     56   public final void tearDown() {
     57     injector.getInstance(UnitOfWork.class).end();
     58     injector.getInstance(EntityManagerFactory.class).close();
     59   }
     60 
     61   public void testSimpleTransaction() {
     62     injector.getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
     63         .runOperationInTxn();
     64 
     65     EntityManager em = injector.getInstance(EntityManager.class);
     66     assertFalse("txn was not closed by transactional service",
     67         em.getTransaction().isActive());
     68 
     69     //test that the data has been stored
     70     Object result = em.createQuery("from JpaTestEntity where text = :text")
     71         .setParameter("text", UNIQUE_TEXT).getSingleResult();
     72     injector.getInstance(UnitOfWork.class).end();
     73 
     74     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);
     75 
     76     assertEquals("queried entity did not match--did automatic txn fail?", UNIQUE_TEXT,
     77         ((JpaTestEntity) result).getText());
     78   }
     79 
     80   public void testSimpleTransactionRollbackOnChecked() {
     81     try {
     82       injector.getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
     83           .runOperationInTxnThrowingChecked();
     84     } catch (IOException e) {
     85       //ignore
     86       injector.getInstance(UnitOfWork.class).end();
     87     }
     88 
     89     EntityManager em = injector.getInstance(EntityManager.class);
     90 
     91     assertFalse("EM was not closed by transactional service (rollback didnt happen?)",
     92         em.getTransaction().isActive());
     93 
     94     //test that the data has been stored
     95     try {
     96       Object result = em.createQuery("from JpaTestEntity where text = :text")
     97           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
     98       injector.getInstance(UnitOfWork.class).end();
     99       fail("a result was returned! rollback sure didnt happen!!!");
    100     } catch (NoResultException e) { }
    101   }
    102 
    103   public void testSimpleTransactionRollbackOnUnchecked() {
    104     try {
    105       injector.getInstance(JoiningLocalTransactionsTest.TransactionalObject.class)
    106           .runOperationInTxnThrowingUnchecked();
    107     } catch (RuntimeException re) {
    108       //ignore
    109       injector.getInstance(UnitOfWork.class).end();
    110     }
    111 
    112     EntityManager em = injector.getInstance(EntityManager.class);
    113     assertFalse("Session was not closed by transactional service (rollback didnt happen?)",
    114         em.getTransaction().isActive());
    115 
    116     try {
    117       Object result = em.createQuery("from JpaTestEntity where text = :text")
    118           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();
    119       injector.getInstance(UnitOfWork.class).end();
    120       fail("a result was returned! rollback sure didnt happen!!!");
    121     } catch (NoResultException e) {}
    122   }
    123 
    124   public static class TransactionalObject {
    125     private final EntityManager em;
    126 
    127     @Inject
    128     public TransactionalObject(EntityManager em) {
    129       this.em = em;
    130     }
    131 
    132     @Transactional
    133     public void runOperationInTxn() {
    134       runOperationInTxnInternal();
    135     }
    136 
    137     @Transactional(rollbackOn = IOException.class)
    138     public void runOperationInTxnInternal() {
    139       JpaTestEntity entity = new JpaTestEntity();
    140       entity.setText(UNIQUE_TEXT);
    141       em.persist(entity);
    142     }
    143 
    144     @Transactional(rollbackOn = IOException.class)
    145     public void runOperationInTxnThrowingChecked() throws IOException {
    146       runOperationInTxnThrowingCheckedInternal();
    147     }
    148 
    149     @Transactional
    150     private void runOperationInTxnThrowingCheckedInternal() throws IOException {
    151       JpaTestEntity entity = new JpaTestEntity();
    152       entity.setText(TRANSIENT_UNIQUE_TEXT);
    153       em.persist(entity);
    154 
    155       throw new IOException();
    156     }
    157 
    158     @Transactional
    159     public void runOperationInTxnThrowingUnchecked() {
    160       runOperationInTxnThrowingUncheckedInternal();
    161     }
    162 
    163     @Transactional(rollbackOn = IOException.class)
    164     public void runOperationInTxnThrowingUncheckedInternal() {
    165       JpaTestEntity entity = new JpaTestEntity();
    166       entity.setText(TRANSIENT_UNIQUE_TEXT);
    167       em.persist(entity);
    168 
    169       throw new IllegalStateException();
    170     }
    171   }
    172 }
    173