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
17package com.google.inject.persist.jpa;
18
19import com.google.inject.Guice;
20import com.google.inject.Inject;
21import com.google.inject.Injector;
22import com.google.inject.persist.PersistService;
23import com.google.inject.persist.Transactional;
24import com.google.inject.persist.UnitOfWork;
25
26import junit.framework.TestCase;
27
28import java.util.Date;
29
30import javax.persistence.EntityManager;
31import javax.persistence.EntityManagerFactory;
32
33/**
34 * For instance, a session-per-request strategy will control the opening and closing of the EM at
35 * its own (manual) discretion. As opposed to a transactional unit of work.
36 *
37 * @author Dhanji R. Prasanna (dhanji@gmail.com)
38 */
39
40public class ManualLocalTransactionsTest extends TestCase {
41  private Injector injector;
42  private static final String UNIQUE_TEXT = "some unique text" + new Date();
43  private static final String UNIQUE_TEXT_2 = "some other unique text" + new Date();
44
45  public void setUp() {
46    injector = Guice.createInjector(new JpaPersistModule("testUnit"));
47
48    //startup persistence
49    injector.getInstance(PersistService.class).start();
50  }
51
52  public void tearDown() {
53    injector.getInstance(EntityManagerFactory.class).close();
54  }
55
56  public void testSimpleCrossTxnWork() {
57    injector.getInstance(UnitOfWork.class).begin();
58
59    //pretend that the request was started here
60    EntityManager em = injector.getInstance(EntityManager.class);
61
62    JpaTestEntity entity = injector.getInstance(TransactionalObject.class).runOperationInTxn();
63    injector.getInstance(TransactionalObject.class).runOperationInTxn2();
64
65    //persisted entity should remain in the same em (which should still be open)
66    assertTrue("EntityManager  appears to have been closed across txns!",
67        injector.getInstance(EntityManager.class).contains(entity));
68    assertTrue("EntityManager  appears to have been closed across txns!", em.contains(entity));
69    assertTrue("EntityManager appears to have been closed across txns!", em.isOpen());
70
71    injector.getInstance(UnitOfWork.class).end();
72    injector.getInstance(UnitOfWork.class).begin();
73
74    //try to query them back out
75    em = injector.getInstance(EntityManager.class);
76    assertNotNull(em.createQuery("from JpaTestEntity where text = :text")
77        .setParameter("text", UNIQUE_TEXT).getSingleResult());
78    assertNotNull(em.createQuery("from JpaTestEntity where text = :text")
79        .setParameter("text", UNIQUE_TEXT_2).getSingleResult());
80    em.close();
81
82    assertFalse(em.isOpen());
83  }
84
85  public static class TransactionalObject {
86    @Inject EntityManager em;
87
88    @Transactional
89    public JpaTestEntity runOperationInTxn() {
90      JpaTestEntity entity = new JpaTestEntity();
91      entity.setText(UNIQUE_TEXT);
92      em.persist(entity);
93
94      return entity;
95    }
96
97    @Transactional
98    public void runOperationInTxn2() {
99      JpaTestEntity entity = new JpaTestEntity();
100      entity.setText(UNIQUE_TEXT_2);
101      em.persist(entity);
102    }
103
104  }
105}
106