/* * Copyright (C) 2010 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.inject.persist.jpa; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.persist.PersistService; import com.google.inject.persist.Transactional; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Date; import java.util.List; import javax.persistence.EntityManager; import junit.framework.TestCase; /** * This test asserts class level @Transactional annotation behavior. * * <p>Class-level @Transactional is a shortcut if all non-private methods in the class are meant to * be transactional. * * @author Dhanji R. Prasanna (dhanji@gmail.com) */ public class ClassLevelManagedLocalTransactionsTest extends TestCase { private Injector injector; private static final String UNIQUE_TEXT = "JPAsome unique text88888" + new Date(); private static final String UNIQUE_TEXT_2 = "JPAsome asda unique teasdalsdplasdxt" + new Date(); private static final String TRANSIENT_UNIQUE_TEXT = "JPAsome other unique texaksoksojadasdt" + new Date(); @Override public void setUp() { injector = Guice.createInjector(new JpaPersistModule("testUnit")); //startup persistence injector.getInstance(PersistService.class).start(); } @Override public void tearDown() { injector.getInstance(PersistService.class).stop(); injector = null; } public void testSimpleTransaction() { injector.getInstance(TransactionalObject.class).runOperationInTxn(); EntityManager session = injector.getInstance(EntityManager.class); assertFalse( "EntityManager was not closed by transactional service", session.getTransaction().isActive()); //test that the data has been stored session.getTransaction().begin(); Object result = session .createQuery("from JpaTestEntity where text = :text") .setParameter("text", UNIQUE_TEXT) .getSingleResult(); session.getTransaction().commit(); assertTrue("odd result returned fatal", result instanceof JpaTestEntity); assertEquals( "queried entity did not match--did automatic txn fail?", UNIQUE_TEXT, (((JpaTestEntity) result).getText())); } public void testSimpleTransactionRollbackOnChecked() { try { injector.getInstance(TransactionalObject2.class).runOperationInTxnThrowingChecked(); } catch (IOException e) { //ignore } EntityManager session = injector.getInstance(EntityManager.class); assertFalse( "EntityManager was not closed by transactional service (rollback didnt happen?)", session.getTransaction().isActive()); //test that the data has been stored session.getTransaction().begin(); List<?> result = session .createQuery("from JpaTestEntity where text = :text") .setParameter("text", TRANSIENT_UNIQUE_TEXT) .getResultList(); session.getTransaction().commit(); assertTrue("a result was returned! rollback sure didnt happen!!!", result.isEmpty()); } public void testSimpleTransactionRollbackOnCheckedExcepting() { Exception ex = null; try { injector.getInstance(TransactionalObject3.class).runOperationInTxnThrowingCheckedExcepting(); fail("Exception was not thrown by test txn-al method!"); } catch (IOException e) { //ignored } EntityManager session = injector.getInstance(EntityManager.class); assertFalse( "Txn was not closed by transactional service (commit didnt happen?)", session.getTransaction().isActive()); //test that the data has been stored session.getTransaction().begin(); Object result = session .createQuery("from JpaTestEntity where text = :text") .setParameter("text", UNIQUE_TEXT_2) .getSingleResult(); session.getTransaction().commit(); assertNotNull("a result was not returned! rollback happened anyway (ignore failed)!!!", result); } public void testSimpleTransactionRollbackOnUnchecked() { try { injector.getInstance(TransactionalObject4.class).runOperationInTxnThrowingUnchecked(); } catch (RuntimeException re) { //ignore } EntityManager session = injector.getInstance(EntityManager.class); assertFalse( "EntityManager was not closed by transactional service (rollback didnt happen?)", session.getTransaction().isActive()); //test that the data has been stored session.getTransaction().begin(); List<?> result = session .createQuery("from JpaTestEntity where text = :text") .setParameter("text", TRANSIENT_UNIQUE_TEXT) .getResultList(); session.getTransaction().commit(); assertTrue("a result was returned! rollback sure didnt happen!!!", result.isEmpty()); } @Transactional public static class TransactionalObject { @Inject EntityManager session; public void runOperationInTxn() { assertTrue(session.getTransaction().isActive()); JpaTestEntity entity = new JpaTestEntity(); entity.setText(UNIQUE_TEXT); session.persist(entity); } } @Transactional public static class TransactionalObject4 { @Inject EntityManager session; @Transactional public void runOperationInTxnThrowingUnchecked() { assertTrue(session.getTransaction().isActive()); JpaTestEntity entity = new JpaTestEntity(); entity.setText(TRANSIENT_UNIQUE_TEXT); session.persist(entity); throw new IllegalStateException(); } } @Transactional(rollbackOn = IOException.class, ignore = FileNotFoundException.class) public static class TransactionalObject3 { @Inject EntityManager session; public void runOperationInTxnThrowingCheckedExcepting() throws IOException { assertTrue(session.getTransaction().isActive()); JpaTestEntity entity = new JpaTestEntity(); entity.setText(UNIQUE_TEXT_2); session.persist(entity); throw new FileNotFoundException(); } } @Transactional(rollbackOn = IOException.class) public static class TransactionalObject2 { @Inject EntityManager session; public void runOperationInTxnThrowingChecked() throws IOException { assertTrue(session.getTransaction().isActive()); JpaTestEntity entity = new JpaTestEntity(); entity.setText(TRANSIENT_UNIQUE_TEXT); session.persist(entity); throw new IOException(); } } }