1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.orchestra.conversation.spring;
20
21 import org.springframework.orm.jpa.EntityManagerHolder;
22 import org.springframework.transaction.support.TransactionSynchronizationManager;
23
24 import javax.persistence.EntityManager;
25 import javax.persistence.EntityManagerFactory;
26 import javax.persistence.FlushModeType;
27 import java.util.Stack;
28
29 /***
30 * A factory for PersistenceContext objects which integrates with Spring's JPA
31 * support.
32 * <p>
33 * When a bean is invoked which is associated with a conversation, but the conversation
34 * does not yet have a PersistenceContext, then this factory is used to create a
35 * PersistenceContext.
36 * <p>
37 * The returned object knows how to configure itself as the "current persistence context"
38 * within Spring when a method on that bean is invoked, and how to restore the earlier
39 * "current persistence context" after the method returns.
40 */
41 public class JpaPersistenceContextFactory implements PersistenceContextFactory
42 {
43 private EntityManagerFactory entityManagerFactory;
44
45 public PersistenceContext create()
46 {
47 final EntityManager em = entityManagerFactory.createEntityManager();
48 em.setFlushMode(FlushModeType.COMMIT);
49
50 return new PersistenceContext()
51 {
52 private final Stack bindings = new Stack();
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public void bind()
75 {
76 synchronized(bindings)
77 {
78 EntityManagerHolder current = (EntityManagerHolder)
79 TransactionSynchronizationManager.getResource(entityManagerFactory);
80
81 if (current != null)
82 {
83 TransactionSynchronizationManager.unbindResource(entityManagerFactory);
84 }
85
86 bindings.push(current);
87
88 TransactionSynchronizationManager.bindResource(entityManagerFactory,
89 new EntityManagerHolder(em));
90 }
91 }
92
93 public void unbind()
94 {
95 synchronized(bindings)
96 {
97 if (TransactionSynchronizationManager.hasResource(entityManagerFactory))
98 {
99 TransactionSynchronizationManager.unbindResource(entityManagerFactory);
100 }
101
102 Object holder = null;
103 if (bindings.size() > 0)
104 {
105 holder = bindings.pop();
106 }
107 if (holder != null)
108 {
109 TransactionSynchronizationManager.bindResource(entityManagerFactory,
110 holder);
111 }
112 }
113 }
114
115 public void close()
116 {
117 em.close();
118 }
119 };
120 }
121
122 public EntityManagerFactory getEntityManagerFactory()
123 {
124 return entityManagerFactory;
125 }
126
127 public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory)
128 {
129 this.entityManagerFactory = entityManagerFactory;
130 }
131 }