DATAJPA-350 - Improve EntityManager usage for query validation.

SimpleJpaQuery now uses an explicitly created EntityManager instance to verify the manually defined query be able to close the instance explicitly. This will improve GCing the instance.
This commit is contained in:
Oliver Gierke
2013-06-03 13:40:47 +02:00
parent 820655a7c4
commit 29dc2cb8a0
3 changed files with 42 additions and 19 deletions

View File

@@ -73,14 +73,32 @@ final class SimpleJpaQuery extends AbstractJpaQuery {
}
}
/**
* Validates the given query for syntactical correctness.
*
* @param query
* @param em
*/
private final void validateQuery(String query, EntityManager em) {
EntityManager validatingEm = null;
try {
em.createQuery(query);
validatingEm = em.getEntityManagerFactory().createEntityManager();
validatingEm.createQuery(query);
} catch (RuntimeException e) {
// Needed as there's ambiguities in how an invalid query string shall be expressed by the persistence provider
// http://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2012-07/message/17
throw e instanceof IllegalArgumentException ? e : new IllegalArgumentException(e);
} finally {
if (validatingEm != null) {
validatingEm.close();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,9 @@ import static org.mockito.Mockito.*;
import java.lang.reflect.Method;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -45,12 +47,16 @@ import org.springframework.data.repository.query.QueryLookupStrategy.Key;
@RunWith(MockitoJUnitRunner.class)
public class JpaQueryLookupStrategyUnitTests {
@Mock
EntityManager em;
@Mock
QueryExtractor extractor;
@Mock
NamedQueries namedQueries;
@Mock EntityManager em;
@Mock EntityManagerFactory emf;
@Mock QueryExtractor extractor;
@Mock NamedQueries namedQueries;
@Before
public void setUp() {
when(em.getEntityManagerFactory()).thenReturn(emf);
when(emf.createEntityManager()).thenReturn(em);
}
/**
* @see DATAJPA-226

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008-2011 the original author or authors.
* Copyright 2008-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.TypedQuery;
import org.junit.Before;
@@ -51,22 +52,20 @@ public class SimpleJpaQueryUnitTests {
JpaQueryMethod method;
@Mock
EntityManager em;
@Mock
QueryExtractor extractor;
@Mock
TypedQuery<Long> query;
@Mock
RepositoryMetadata metadata;
@Mock
ParameterBinder binder;
@Mock EntityManager em;
@Mock EntityManagerFactory emf;
@Mock QueryExtractor extractor;
@Mock TypedQuery<Long> query;
@Mock RepositoryMetadata metadata;
@Mock ParameterBinder binder;
@Before
public void setUp() throws SecurityException, NoSuchMethodException {
when(em.createQuery(anyString())).thenReturn(query);
when(em.createQuery(anyString(), eq(Long.class))).thenReturn(query);
when(em.getEntityManagerFactory()).thenReturn(emf);
when(emf.createEntityManager()).thenReturn(em);
Method setUp = UserRepository.class.getMethod("findByLastname", String.class);
method = new JpaQueryMethod(setUp, metadata, extractor);