Repository: olingo-odata2 Updated Branches: refs/heads/master 2e26075a1 -> 10a2da0e0
[OLINGO-670] Close Entity Manager after every OData JPA Processor call. However in case of $batch calls close the entity manager at the end of every change set. Change-Id: I09c5ab8676f53abe7db8c23033dd9ac1fc948d6e Signed-off-by: Chandan V A <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/10a2da0e Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/10a2da0e Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/10a2da0e Branch: refs/heads/master Commit: 10a2da0e024df2e04745a1c17b8f14a4805f4432 Parents: 2e26075 Author: Chandan V A <[email protected]> Authored: Tue Jun 9 12:36:11 2015 +0530 Committer: Chandan V A <[email protected]> Committed: Tue Jun 9 12:36:11 2015 +0530 ---------------------------------------------------------------------- .../jpa/processor/api/ODataJPAProcessor.java | 14 +- .../jpa/processor/core/ODataJPAContextImpl.java | 5 +- .../core/ODataJPAProcessorDefault.java | 248 ++++++++++--------- .../processor/core/ODataJPAContextImplTest.java | 1 + .../core/ODataJPAProcessorDefaultTest.java | 8 +- .../core/access/data/JPAProcessorImplTest.java | 2 +- 6 files changed, 154 insertions(+), 124 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/10a2da0e/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAProcessor.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAProcessor.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAProcessor.java index 3a1b179..dc29caa 100644 --- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAProcessor.java +++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAProcessor.java @@ -18,6 +18,8 @@ ******************************************************************************/ package org.apache.olingo.odata2.jpa.processor.api; +import javax.persistence.EntityManager; + import org.apache.olingo.odata2.api.processor.ODataSingleProcessor; import org.apache.olingo.odata2.jpa.processor.api.access.JPAProcessor; import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAException; @@ -78,8 +80,18 @@ public abstract class ODataJPAProcessor extends ODataSingleProcessor { * The method closes ThreadContext. It is mandatory to call this method to * avoid memory leaks. */ - public void close() { + public void close(boolean forceClose) { ODataJPATombstoneContext.cleanup(); + EntityManager em = oDataJPAContext.getEntityManager(); + if (!oDataJPAContext.getODataContext().isInBatchMode() || forceClose) { + if (em.isOpen()) { + em.close(); + } + } + } + + public void close() { + close(false); } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/10a2da0e/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImpl.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImpl.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImpl.java index 0da67e1..1c46dd4 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImpl.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImpl.java @@ -33,7 +33,7 @@ public class ODataJPAContextImpl implements ODataJPAContext { private String pUnitName; private EntityManagerFactory emf; - private EntityManager em; + private EntityManager em = null; private ODataContext odataContext; private ODataProcessor processor; private EdmProvider edmProvider; @@ -121,10 +121,9 @@ public class ODataJPAContextImpl implements ODataJPAContext { @Override public EntityManager getEntityManager() { - if (em == null) { + if (em == null || !em.isOpen()) { em = emf.createEntityManager(); } - return em; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/10a2da0e/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefault.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefault.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefault.java index 2bc2635..c09864e 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefault.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefault.java @@ -58,205 +58,220 @@ public class ODataJPAProcessorDefault extends ODataJPAProcessor { @Override public ODataResponse readEntitySet(final GetEntitySetUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - List<Object> jpaEntities = jpaProcessor.process(uriParserResultView); - - ODataResponse oDataResponse = - responseBuilder.build(uriParserResultView, jpaEntities, contentType); - - close(); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + List<Object> jpaEntities = jpaProcessor.process(uriParserResultView); + oDataResponse = + responseBuilder.build(uriParserResultView, jpaEntities, contentType); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse readEntity(final GetEntityUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - Object jpaEntity = jpaProcessor.process(uriParserResultView); - - ODataResponse oDataResponse = - responseBuilder.build(uriParserResultView, jpaEntity, contentType); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + Object jpaEntity = jpaProcessor.process(uriParserResultView); + oDataResponse = + responseBuilder.build(uriParserResultView, jpaEntity, contentType); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse countEntitySet(final GetEntitySetCountUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - long jpaEntityCount = jpaProcessor.process(uriParserResultView); - - ODataResponse oDataResponse = responseBuilder.build(jpaEntityCount); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + long jpaEntityCount = jpaProcessor.process(uriParserResultView); + oDataResponse = responseBuilder.build(jpaEntityCount); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse existsEntity(final GetEntityCountUriInfo uriInfo, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - long jpaEntityCount = jpaProcessor.process(uriInfo); - - ODataResponse oDataResponse = responseBuilder.build(jpaEntityCount); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + long jpaEntityCount = jpaProcessor.process(uriInfo); + oDataResponse = responseBuilder.build(jpaEntityCount); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse createEntity(final PostUriInfo uriParserResultView, final InputStream content, final String requestContentType, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - Object createdJpaEntity = jpaProcessor.process(uriParserResultView, content, requestContentType); - - ODataResponse oDataResponse = - responseBuilder.build(uriParserResultView, createdJpaEntity, contentType); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + Object createdJpaEntity = jpaProcessor.process(uriParserResultView, content, requestContentType); + oDataResponse = + responseBuilder.build(uriParserResultView, createdJpaEntity, contentType); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse updateEntity(final PutMergePatchUriInfo uriParserResultView, final InputStream content, final String requestContentType, final boolean merge, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - Object jpaEntity = jpaProcessor.process(uriParserResultView, content, requestContentType); - - ODataResponse oDataResponse = responseBuilder.build(uriParserResultView, jpaEntity); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + Object jpaEntity = jpaProcessor.process(uriParserResultView, content, requestContentType); + oDataResponse = responseBuilder.build(uriParserResultView, jpaEntity); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse deleteEntity(final DeleteUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - Object deletedObj = jpaProcessor.process(uriParserResultView, contentType); - - ODataResponse oDataResponse = responseBuilder.build(uriParserResultView, deletedObj); + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + Object deletedObj = jpaProcessor.process(uriParserResultView, contentType); + oDataResponse = responseBuilder.build(uriParserResultView, deletedObj); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse executeFunctionImport(final GetFunctionImportUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - List<Object> resultEntity = jpaProcessor.process(uriParserResultView); - - ODataResponse oDataResponse = - responseBuilder.build(uriParserResultView, resultEntity, contentType); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + List<Object> resultEntity = jpaProcessor.process(uriParserResultView); + oDataResponse = + responseBuilder.build(uriParserResultView, resultEntity, contentType); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse executeFunctionImportValue(final GetFunctionImportUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - List<Object> result = jpaProcessor.process(uriParserResultView); - - ODataResponse oDataResponse = - responseBuilder.build(uriParserResultView, result.get(0)); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + List<Object> result = jpaProcessor.process(uriParserResultView); + oDataResponse = + responseBuilder.build(uriParserResultView, result.get(0)); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse readEntityLink(final GetEntityLinkUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - Object jpaEntity = jpaProcessor.process(uriParserResultView); - - ODataResponse oDataResponse = - responseBuilder.build(uriParserResultView, jpaEntity, contentType); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + Object jpaEntity = jpaProcessor.process(uriParserResultView); + oDataResponse = + responseBuilder.build(uriParserResultView, jpaEntity, contentType); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse readEntityLinks(final GetEntitySetLinksUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - List<Object> jpaEntity = jpaProcessor.process(uriParserResultView); - - ODataResponse oDataResponse = - responseBuilder.build(uriParserResultView, jpaEntity, contentType); - + ODataResponse oDataResponse = null; + try { + oDataJPAContext.setODataContext(getContext()); + List<Object> jpaEntity = jpaProcessor.process(uriParserResultView); + oDataResponse = + responseBuilder.build(uriParserResultView, jpaEntity, contentType); + } finally { + close(); + } return oDataResponse; } @Override public ODataResponse createEntityLink(final PostUriInfo uriParserResultView, final InputStream content, final String requestContentType, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - jpaProcessor.process(uriParserResultView, content, requestContentType, contentType); - - return ODataResponse.newBuilder().build(); + try { + oDataJPAContext.setODataContext(getContext()); + jpaProcessor.process(uriParserResultView, content, requestContentType, contentType); + return ODataResponse.newBuilder().build(); + } finally { + close(); + } } @Override public ODataResponse updateEntityLink(final PutMergePatchUriInfo uriParserResultView, final InputStream content, final String requestContentType, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - jpaProcessor.process(uriParserResultView, content, requestContentType, contentType); - - return ODataResponse.newBuilder().build(); + try { + oDataJPAContext.setODataContext(getContext()); + jpaProcessor.process(uriParserResultView, content, requestContentType, contentType); + return ODataResponse.newBuilder().build(); + } finally { + close(); + } } @Override public ODataResponse deleteEntityLink(final DeleteUriInfo uriParserResultView, final String contentType) throws ODataException { - - oDataJPAContext.setODataContext(getContext()); - - jpaProcessor.process(uriParserResultView, contentType); - return ODataResponse.newBuilder().build(); - + try { + oDataJPAContext.setODataContext(getContext()); + jpaProcessor.process(uriParserResultView, contentType); + return ODataResponse.newBuilder().build(); + } finally { + close(); + } } @Override public ODataResponse executeBatch(final BatchHandler handler, final String contentType, final InputStream content) throws ODataException { + try { + oDataJPAContext.setODataContext(getContext()); - oDataJPAContext.setODataContext(getContext()); - - ODataResponse batchResponse; - List<BatchResponsePart> batchResponseParts = new ArrayList<BatchResponsePart>(); - PathInfo pathInfo = getContext().getPathInfo(); - EntityProviderBatchProperties batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build(); - List<BatchRequestPart> batchParts = EntityProvider.parseBatchRequest(contentType, content, batchProperties); + ODataResponse batchResponse; + List<BatchResponsePart> batchResponseParts = new ArrayList<BatchResponsePart>(); + PathInfo pathInfo = getContext().getPathInfo(); + EntityProviderBatchProperties batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build(); + List<BatchRequestPart> batchParts = EntityProvider.parseBatchRequest(contentType, content, batchProperties); - for (BatchRequestPart batchPart : batchParts) { - batchResponseParts.add(handler.handleBatchPart(batchPart)); + for (BatchRequestPart batchPart : batchParts) { + batchResponseParts.add(handler.handleBatchPart(batchPart)); + } + batchResponse = EntityProvider.writeBatchResponse(batchResponseParts); + return batchResponse; + } finally { + close(true); } - batchResponse = EntityProvider.writeBatchResponse(batchResponseParts); - return batchResponse; - } @Override @@ -280,13 +295,14 @@ public class ODataJPAProcessorDefault extends ODataJPAProcessor { } oDataJPAContext.getODataJPATransaction().commit(); - return BatchResponsePart.responses(responses).changeSet(true).build(); } catch (Exception e) { List<ODataResponse> errorResponses = new ArrayList<ODataResponse>(1); errorResponses.add(ODataResponse.entity(e).status(HttpStatusCodes.INTERNAL_SERVER_ERROR).build()); return BatchResponsePart.responses(errorResponses).changeSet(false).build(); + } finally { + close(true); } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/10a2da0e/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImplTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImplTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImplTest.java index 7550c00..83952d0 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImplTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAContextImplTest.java @@ -52,6 +52,7 @@ public class ODataJPAContextImplTest { edmProvider = new ODataJPAEdmProvider(); emf = EasyMock.createMock(EntityManagerFactory.class); em = EasyMock.createMock(EntityManager.class); + EasyMock.expect(em.isOpen()).andReturn(false); EasyMock.replay(em); EasyMock.expect(emf.createEntityManager()).andStubReturn(em); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/10a2da0e/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java index ba43d37..8f7a413 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java @@ -87,13 +87,11 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView { private static final String SALES_ORDER = "SalesOrder"; private static final String SALES_ORDER_HEADERS = "SalesOrderHeaders"; private static final String STR_CONTENT_TYPE = "Content-Type"; - @Before public void setUp() { objODataJPAProcessorDefault = new ODataJPAProcessorDefault(getLocalmockODataJPAContext()); } - @Test public void testReadEntitySetGetEntitySetUriInfoString() { @@ -172,7 +170,7 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView { Assert.assertTrue(true); // Expected TODO - need to revisit } } - + private PutMergePatchUriInfo getPutUriInfo() { return (PutMergePatchUriInfo) getDeletetUriInfo(); } @@ -362,9 +360,12 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView { getQueryForSelectCount()); EasyMock.expect(em.getEntityManagerFactory()).andStubReturn(mockEntityManagerFactory2());// For create EasyMock.expect(em.getTransaction()).andStubReturn(getLocalTransaction()); // For Delete + EasyMock.expect(em.isOpen()).andReturn(true).anyTimes(); Address obj = new Address(); em.remove(obj);// testing void method em.flush(); + em.close(); + EasyMock.expectLastCall().anyTimes(); EasyMock.replay(em); return em; } @@ -543,6 +544,7 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView { ODataContext objODataContext = EasyMock.createMock(ODataContext.class); try { EasyMock.expect(objODataContext.getPathInfo()).andStubReturn(getLocalPathInfo()); + EasyMock.expect(objODataContext.isInBatchMode()).andReturn(false).anyTimes(); } catch (ODataException e) { fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2); } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/10a2da0e/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java index 01e726d..a62096b 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java @@ -308,7 +308,6 @@ public class JPAProcessorImplTest { return tx; } - private EntityManagerFactory mockEntityManagerFactory() { EntityManagerFactory emf = EasyMock.createMock(EntityManagerFactory.class); EasyMock.expect(emf.getMetamodel()).andStubReturn(mockMetaModel()); @@ -323,6 +322,7 @@ public class JPAProcessorImplTest { EasyMock.expect(em.createQuery("SELECT COUNT ( E1 ) FROM SalesOrderHeaders E1")).andStubReturn( getQueryForSelectCount()); EasyMock.expect(em.getTransaction()).andStubReturn(getLocalTransaction()); // For Delete + EasyMock.expect(em.isOpen()).andReturn(false); em.flush(); em.flush(); Address obj = new Address();
