1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.orm.jpa.vendor;
17
18 import java.sql.Connection;
19 import java.sql.SQLException;
20 import javax.persistence.EntityManager;
21 import javax.persistence.PersistenceException;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.openjpa.persistence.FetchPlan;
24 import org.apache.openjpa.persistence.OpenJPAEntityManager;
25 import org.apache.openjpa.persistence.OpenJPAPersistence;
26 import org.apache.openjpa.persistence.jdbc.IsolationLevel;
27 import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
28 import org.springframework.jdbc.datasource.ConnectionHandle;
29 import org.springframework.jdbc.datasource.ConnectionHolder;
30 import org.springframework.jdbc.support.JdbcUtils;
31 import org.springframework.orm.jpa.DefaultJpaDialect;
32 import org.springframework.transaction.SavepointManager;
33 import org.springframework.transaction.TransactionDefinition;
34 import org.springframework.transaction.TransactionException;
35
36
37
38
39
40
41
42
43
44 public class OpenJpaDialect extends DefaultJpaDialect {
45
46 private static final long serialVersionUID = 2099118508988476959L;
47
48 @Override
49 public Object beginTransaction(final EntityManager entityManager, final TransactionDefinition definition)
50 throws PersistenceException, SQLException, TransactionException {
51
52 OpenJPAEntityManager openJpaEntityManager = getOpenJPAEntityManager(entityManager);
53
54 if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
55
56 FetchPlan fetchPlan = openJpaEntityManager.getFetchPlan();
57 if (fetchPlan instanceof JDBCFetchPlan) {
58 IsolationLevel isolation = IsolationLevel.fromConnectionConstant(definition.getIsolationLevel());
59 ((JDBCFetchPlan) fetchPlan).setIsolation(isolation);
60 }
61 }
62
63 entityManager.getTransaction().begin();
64
65 if (!definition.isReadOnly()) {
66
67
68 openJpaEntityManager.beginStore();
69 }
70
71
72 return new OpenJpaTransactionData(openJpaEntityManager);
73 }
74
75 @Override
76 public ConnectionHandle getJdbcConnection(final EntityManager entityManager, final boolean readOnly)
77 throws PersistenceException, SQLException {
78
79 return new OpenJpaConnectionHandle(getOpenJPAEntityManager(entityManager));
80 }
81
82
83
84
85
86
87
88 protected static OpenJPAEntityManager getOpenJPAEntityManager(final EntityManager em) {
89 return OpenJPAPersistence.cast(em);
90 }
91
92
93
94
95
96 private static class OpenJpaTransactionData implements SavepointManager {
97
98 private final OpenJPAEntityManager entityManager;
99
100 private int savepointCounter = 0;
101
102 OpenJpaTransactionData(final OpenJPAEntityManager entityManager) {
103 this.entityManager = entityManager;
104 }
105
106 @Override
107 public Object createSavepoint() throws TransactionException {
108 this.savepointCounter++;
109 String savepointName = ConnectionHolder.SAVEPOINT_NAME_PREFIX + this.savepointCounter;
110 this.entityManager.setSavepoint(savepointName);
111 return savepointName;
112 }
113
114 @Override
115 public void rollbackToSavepoint(final Object savepoint) throws TransactionException {
116 this.entityManager.rollbackToSavepoint((String) savepoint);
117 }
118
119 @Override
120 public void releaseSavepoint(final Object savepoint) throws TransactionException {
121 try {
122 this.entityManager.releaseSavepoint((String) savepoint);
123 } catch (Throwable ex) {
124 LogFactory.getLog(OpenJpaTransactionData.class).debug(
125 "Could not explicitly release OpenJPA savepoint", ex);
126 }
127 }
128 }
129
130
131
132
133
134
135
136
137
138 private static class OpenJpaConnectionHandle implements ConnectionHandle {
139
140 private final OpenJPAEntityManager entityManager;
141
142 OpenJpaConnectionHandle(final OpenJPAEntityManager entityManager) {
143 this.entityManager = entityManager;
144 }
145
146 @Override
147 public Connection getConnection() {
148 return (Connection) this.entityManager.getConnection();
149 }
150
151 @Override
152 public void releaseConnection(final Connection con) {
153 JdbcUtils.closeConnection(con);
154 }
155 }
156 }