Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support $batch operations #1

Open
lasterra opened this issue Apr 22, 2016 · 3 comments
Open

Support $batch operations #1

lasterra opened this issue Apr 22, 2016 · 3 comments

Comments

@lasterra
Copy link

In the SevletRegister you need to configure multipart to support batch operations.

Just include this line

odataServletRegistrationBean.setMultipartConfig(new MultipartConfigElement(""));

Thanks for your example, it was very helpful.

@mjza
Copy link

mjza commented Jun 9, 2020

For supporting batch this is not enough, however I am not sure that can even help. For me batch is working as soon as we have only one changeset. As soon as we want to send multiple changes sets in one batch like this:

--batch_ffec-4d8c-af56
Content-Type: multipart/mixed; boundary=changeset_aec6-3a75-e9ea

--changeset_aec6-3a75-e9ea
Content-Type: application/http
Content-Transfer-Encoding: binary

MERGE QuestionSet(6) HTTP/1.1
sap-contextid-accept: header
Accept: application/json
Accept-Language: en-US
DataServiceVersion: 2.0
MaxDataServiceVersion: 2.0
Content-Type: application/json
Content-Length: 141

{"Deleted":false,"FormId":2,"Id":6,"Mandatory":true,"QtypeId":"QT2","Question":"Do you like your manager?","RandomWeight":"1.0","Sequence":1}
--changeset_aec6-3a75-e9ea--

--batch_ffec-4d8c-af56
Content-Type: multipart/mixed; boundary=changeset_4289-845e-d51d

--changeset_4289-845e-d51d
Content-Type: application/http
Content-Transfer-Encoding: binary

MERGE QuestionSet(5) HTTP/1.1
sap-contextid-accept: header
Accept: application/json
Accept-Language: en-US
DataServiceVersion: 2.0
MaxDataServiceVersion: 2.0
Content-Type: application/json
Content-Length: 157

{"Deleted":false,"FormId":2,"Id":5,"Mandatory":false,"QtypeId":"QT1","Question":"How do you like working with him or her?","RandomWeight":"1.0","Sequence":1}
--changeset_4289-845e-d51d--

--batch_ffec-4d8c-af56
Content-Type: multipart/mixed; boundary=changeset_714c-f47d-1abd

--changeset_714c-f47d-1abd
Content-Type: application/http
Content-Transfer-Encoding: binary

MERGE QuestionSet(20) HTTP/1.1
sap-contextid-accept: header
Accept: application/json
Accept-Language: en-US
DataServiceVersion: 2.0
MaxDataServiceVersion: 2.0
Content-Type: application/json
Content-Length: 187

{"Deleted":false,"FormId":2,"Id":20,"Mandatory":false,"QtypeId":"QT6","Question":"What are the things you like about your manager’s leadership style?","RandomWeight":"1.0","Sequence":3}
--changeset_714c-f47d-1abd--

--batch_ffec-4d8c-af56--

then it will show the following error:

<?xml version='1.0' encoding='UTF-8'?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
    <code/>
    <message xml:lang="en">Error on processing request content:Cannot begin Transaction on closed Session/EntityManager</message>
</error>

@mjza
Copy link

mjza commented Jun 9, 2020

The solution is overriding the executeChangeSet of ODataJPADefaultProcessor class. The problem comes from a commiting function that will close the session:

@Override
public ODataResponse executeBatch(final BatchHandler handler, final String contentType, final InputStream content)
		throws ODataException {
	try {
		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));
		}
		batchResponse = EntityProvider.writeBatchResponse(batchResponseParts);
		return batchResponse;
	} finally {
		close(true);
	}
}

@Override
  public BatchResponsePart executeChangeSet(final BatchHandler handler, final List<ODataRequest> requests)
      throws ODataException {
    List<ODataResponse> responses = new ArrayList<ODataResponse>();
    try {
      //oDataJPAContext.getODataJPATransaction().begin();

      for (ODataRequest request : requests) {
        //oDataJPAContext.setODataContext(getContext());
        ODataResponse response = handler.handleRequest(request);
        if (response.getStatus().getStatusCode() >= HttpStatusCodes.BAD_REQUEST.getStatusCode()) {
          // Roll Back
          oDataJPAContext.getODataJPATransaction().rollback();
          List<ODataResponse> errorResponses = new ArrayList<ODataResponse>(1);
          errorResponses.add(response);
          return BatchResponsePart.responses(errorResponses).changeSet(false).build();
        }
        responses.add(response);
      }
      //oDataJPAContext.getODataJPATransaction().commit();
      return BatchResponsePart.responses(responses).changeSet(true).build();
    } catch (Exception e) {
      throw new ODataException("Error on processing request content:" + e.getMessage(), e);
    } finally {
      close(true);
    }
  }

I have commented the two problematic lines!

@Nihar41
Copy link

Nihar41 commented Jul 13, 2023

Hey you have mentioned that you have commented 2 lines but in the above code 3 lines seem to be committed.
Can you confirm is it required to comment oDataJPAContext.setODataContext(getContext()); also.
For me its working fine without commenting this line and commenting the other 2 lines.
Thanks in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants