Skip to content

Commit ff8c2f7

Browse files
committed
Some changes to session management and how that is handled in the JPA plugin
1 parent af20702 commit ff8c2f7

File tree

5 files changed

+100
-16
lines changed

5 files changed

+100
-16
lines changed

Diff for: grails-datastore-gorm-jpa/src/main/groovy/org/grails/datastore/gorm/jpa/JpaGormEnhancer.groovy

+32
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import org.springframework.orm.jpa.JpaCallback
3030
import org.springframework.orm.jpa.JpaTemplate
3131
import org.springframework.transaction.PlatformTransactionManager
3232
import static org.grails.datastore.mapping.validation.ValidatingEventListener.*
33+
import org.grails.datastore.mapping.jpa.JpaDatastore
34+
import org.grails.datastore.mapping.core.VoidSessionCallback
3335

3436
/**
3537
* Extends the default {@link GormEnhancer} adding supporting for JPQL methods
@@ -57,10 +59,26 @@ class JpaGormEnhancer extends GormEnhancer {
5759
}
5860

5961
class JpaInstanceApi<D> extends GormInstanceApi<D> {
62+
63+
6064

6165
JpaInstanceApi(Class<D> persistentClass, Datastore datastore) {
6266
super(persistentClass, datastore)
6367
}
68+
69+
70+
@Override
71+
protected void execute(VoidSessionCallback callback) {
72+
def session = datastore.connect()
73+
callback.doInSession(session)
74+
}
75+
76+
@Override
77+
protected def <T> T execute(SessionCallback<T> callback) {
78+
def session = datastore.connect()
79+
callback.doInSession(session)
80+
}
81+
6482

6583
D merge(instance, Map params) {
6684
def merged
@@ -128,6 +146,20 @@ class JpaStaticApi<D> extends GormStaticApi<D> {
128146
})
129147
}
130148

149+
@Override
150+
protected void execute(VoidSessionCallback callback) {
151+
def session = datastore.connect()
152+
callback.doInSession(session)
153+
}
154+
155+
@Override
156+
protected def <T> T execute(SessionCallback<T> callback) {
157+
def session = datastore.connect()
158+
callback.doInSession(session)
159+
}
160+
161+
162+
131163
@Override
132164
List<D> executeQuery(String query) {
133165
doQuery query

Diff for: grails-datastore-gorm-jpa/src/main/groovy/org/grails/datastore/gorm/jpa/support/JpaPersistenceContextInterceptor.java

+52-14
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,76 @@
1414
*/
1515
package org.grails.datastore.gorm.jpa.support;
1616

17-
import org.grails.datastore.gorm.support.DatastorePersistenceContextInterceptor;
18-
import org.grails.datastore.mapping.core.DatastoreUtils;
19-
import org.grails.datastore.mapping.core.Session;
17+
import org.codehaus.groovy.grails.support.PersistenceContextInterceptor;
2018
import org.grails.datastore.mapping.jpa.JpaDatastore;
21-
import org.grails.datastore.mapping.transactions.SessionHolder;
22-
import org.springframework.transaction.support.TransactionSynchronizationManager;
19+
import org.grails.datastore.mapping.jpa.JpaSession;
20+
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
21+
import org.springframework.orm.jpa.JpaCallback;
22+
import org.springframework.orm.jpa.JpaTemplate;
23+
24+
import javax.persistence.EntityManager;
25+
import javax.persistence.FlushModeType;
26+
import javax.persistence.PersistenceException;
2327

2428
/**
2529
* @author Graeme Rocher
2630
* @since 1.0
2731
*/
28-
public class JpaPersistenceContextInterceptor extends DatastorePersistenceContextInterceptor {
32+
public class JpaPersistenceContextInterceptor implements PersistenceContextInterceptor {
2933

3034
private JpaDatastore jpaDatastore;
35+
private EntityManager entityManager;
3136

3237
public JpaPersistenceContextInterceptor(JpaDatastore datastore) {
33-
super(datastore);
34-
this.jpaDatastore = datastore;
38+
this.jpaDatastore= datastore;
39+
}
40+
41+
@Override
42+
public void init() {
43+
entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(jpaDatastore.getEntityManagerFactory());
3544
}
3645

3746
@Override
38-
protected Session getSession() {
39-
SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.getResource(jpaDatastore);
40-
if (sessionHolder != null) {
41-
return sessionHolder.getSession();
47+
public void destroy() {
48+
entityManager = null;
49+
}
50+
51+
@Override
52+
public void disconnect() {
53+
if(entityManager != null) {
54+
EntityManagerFactoryUtils.closeEntityManager(entityManager);
4255
}
4356

44-
return DatastoreUtils.bindSession(jpaDatastore.connect());
57+
}
58+
59+
@Override
60+
public void reconnect() {
61+
entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(jpaDatastore.getEntityManagerFactory());
4562
}
4663

4764
@Override
4865
public void flush() {
49-
// do nothing
66+
if(JpaSession.hasTransaction())
67+
entityManager.flush();
68+
}
69+
70+
@Override
71+
public void clear() {
72+
entityManager.clear();
73+
}
74+
75+
@Override
76+
public void setReadOnly() {
77+
entityManager.setFlushMode(FlushModeType.COMMIT);
78+
}
79+
80+
@Override
81+
public void setReadWrite() {
82+
entityManager.setFlushMode(FlushModeType.AUTO);
83+
}
84+
85+
@Override
86+
public boolean isOpen() {
87+
return entityManager != null && entityManager.isOpen();
5088
}
5189
}

Diff for: grails-datastore-gorm-jpa/src/main/resources/org/grails/datastore/gorm/jpa/AddErrors.script

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import org.codehaus.groovy.ast.ClassNode;
55
import org.codehaus.groovy.ast.FieldNode;
66
import org.codehaus.groovy.ast.AnnotatedNode;
77
import org.codehaus.groovy.ast.AnnotationNode;
8-
8+
import org.codehaus.groovy.ast.ASTNode;
9+
import org.codehaus.groovy.ast.expr.ConstantExpression;
10+
import java.lang.reflect.Modifier
11+
import org.springframework.validation.Errors
912

1013
def errorsHelper = new ASTValidationErrorsHelper() {
1114
protected void addErrorsField(ClassNode paramTypeClassNode) {

Diff for: grails-datastore-jpa/src/main/groovy/org/grails/datastore/mapping/jpa/JpaDatastore.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class JpaDatastore extends AbstractDatastore {
3535

3636
private EntityManagerFactory entityManagerFactory;
3737
private JpaTransactionManager transactionManager;
38+
private JpaTemplate jpaTemplate;
3839

3940
public JpaDatastore(MappingContext mappingContext,
4041
EntityManagerFactory entityManagerFactory,
@@ -43,6 +44,7 @@ public JpaDatastore(MappingContext mappingContext,
4344
super(mappingContext, null, applicationContext);
4445
this.entityManagerFactory = entityManagerFactory;
4546
this.transactionManager = transactionManager;
47+
this.jpaTemplate = new JpaTemplate(entityManagerFactory);
4648
initializeConverters(mappingContext);
4749
}
4850

@@ -59,8 +61,13 @@ public JpaTransactionManager getTransactionManager() {
5961
return transactionManager;
6062
}
6163

64+
65+
public JpaTemplate getJpaTemplate() {
66+
return jpaTemplate;
67+
}
68+
6269
@Override
6370
protected Session createSession(Map<String, String> connDetails) {
64-
return new JpaSession(this, new JpaTemplate(entityManagerFactory), transactionManager);
71+
return new JpaSession(this, jpaTemplate, transactionManager);
6572
}
6673
}

Diff for: grails-datastore-jpa/src/main/groovy/org/grails/datastore/mapping/jpa/query/JpaQuery.java

+4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public void add(Criterion criterion) {
7474
@Override
7575
protected List executeQuery(final PersistentEntity entity, final Junction criteria) {
7676
final JpaTemplate jpaTemplate = getSession().getJpaTemplate();
77+
if(!JpaSession.hasTransaction())
78+
jpaTemplate.setFlushEager(false);
7779

7880
return (List)jpaTemplate.execute(new JpaCallback<Object>() {
7981
public Object doInJpa(EntityManager em) throws PersistenceException {
@@ -85,6 +87,8 @@ public Object doInJpa(EntityManager em) throws PersistenceException {
8587
@Override
8688
public Object singleResult() {
8789
final JpaTemplate jpaTemplate = getSession().getJpaTemplate();
90+
if(!JpaSession.hasTransaction())
91+
jpaTemplate.setFlushEager(false);
8892
try {
8993
return jpaTemplate.execute(new JpaCallback<Object>() {
9094
public Object doInJpa(EntityManager em) throws PersistenceException {

0 commit comments

Comments
 (0)