The JPA Processor fills the gap between Olingo V4 and the database, by providing a mapping between JPA metadata and OData metadata, generating queries and supporting the entity manipulations.
For reproducing purposes, lets assume that we have 2 APIs pointing to 1 Bundle which Bundle has 1 Destination.
If we call /v0/consumptionBundles?$expand=destinations everything is OK -> we receive 1 Bundle with 1 Destination.
However, if we call /v0/apis?$expand=consumptionBundles($expand=destinations) there are duplicate Destinations in the response -> we receive 2 APIs (OK) with 1 Bundle in each (OK) with 2 same Destinations in each Bundle (should be 1 Dest):
Note: this issue may sound similar to [this one](https://github.com/SAP/olingo-jpa-processor-v4/issues/276) I recently opened, but there the problem was that we had missing JOIN columns which affected the uniqueness in the response which is not the case here.
Hello,
We have
Bundle
entity in our domain which hasManyToMany
relation to bothAPI
andDestination
entities:Bundle
API
Destination
For reproducing purposes, lets assume that we have 2
APIs
pointing to 1Bundle
which Bundle has 1Destination
.If we call
/v0/consumptionBundles?$expand=destinations
everything is OK -> we receive 1Bundle
with 1Destination
.However, if we call
/v0/apis?$expand=consumptionBundles($expand=destinations)
there are duplicateDestinations
in the response -> we receive 2APIs
(OK) with 1Bundle
in each (OK) with 2 sameDestinations
in each Bundle (should be 1 Dest):To locally reproduce this issue, you can:
--
INSERT INTO public.applications (id, name, description, status_condition, status_timestamp, healthcheck_url, integration_system_id, provider_name, base_url, labels, ready, created_at, updated_at, deleted_at, error, app_template_id, correlation_ids, system_number, documentation_labels, system_status, local_tenant_id, application_namespace, tags) VALUES ('4c63e3b2-3301-4796-bc95-9fb5b2780342', 'system-instance-name', null, 'INITIAL', '2024-02-28 11:56:35.483467', null, null, 'compass', null, null, true, '2024-02-28 11:56:35.483562', null, null, null, null, null, null, null, null, null, null, null);
--
INSERT INTO public.tenant_applications (tenant_id, id, owner, source) VALUES ('3e64ebae-38b5-46a0-b1ed-9ccee153a0ae', '4c63e3b2-3301-4796-bc95-9fb5b2780342', true, '3e64ebae-38b5-46a0-b1ed-9ccee153a0ae');
--
INSERT INTO public.bundles (id, app_id, name, description, instance_auth_request_json_schema, default_instance_auth, ord_id, short_description, links, labels, credential_exchange_strategies, ready, created_at, updated_at, deleted_at, error, correlation_ids, documentation_labels, tags, version, resource_hash, local_tenant_id, app_template_version_id, last_update) VALUES ('96fbf863-93ad-4c59-9464-61753e212e77', '4c63e3b2-3301-4796-bc95-9fb5b2780342', 'foo', 'Foo bar', null, null, null, null, null, null, null, true, '2024-02-28 11:56:35.551719', null, null, null, null, null, null, null, null, null, null, null);
INSERT INTO public.app_templates (id, name, description, application_input, placeholders, access_level, application_namespace, created_at, updated_at) VALUES ('49d9b48b-efea-4935-a7f3-c0ca61223206', 'SAP app-template-name', 'app-template-desc', '{"name": "{{name}}", "labels": {"a": ["b", "c"], "d": ["e", "f"], "applicationType": "SAP app-template-name"}, "baseUrl": null, "bundles": null, "webhooks": [{"url": "http://url.com", "auth": null, "mode": null, "type": "CONFIGURATION_CHANGED", "timeout": null, "version": null, "urlTemplate": null, "inputTemplate": null, "retryInterval": null, "headerTemplate": null, "outputTemplate": null, "statusTemplate": null, "correlationIdKey": null}], "description": "test {{display-name}}", "providerName": "compass-tests", "localTenantID": null, "healthCheckURL": "http://url.valid", "statusCondition": null, "integrationSystemID": null, "applicationNamespace": null}', '[{"Name": "name", "JSONPath": "new-placeholder-name-json-path", "Optional": null, "Description": "app"}, {"Name": "display-name", "JSONPath": "new-placeholder-display-name-json-path", "Optional": null, "Description": "new-placeholder-display-name"}]', 'GLOBAL', null, '2024-03-07 17:39:49.711056', '2024-03-07 17:39:49.711056');
INSERT INTO public.app_template_versions (id, app_template_id, version, title, correlation_ids, release_date, created_at) VALUES ('54d9b48b-efea-4935-a7f3-c0ca61223206', '49d9b48b-efea-4935-a7f3-c0ca61223206', '1', null, null, null, '2024-03-07 17:40:12.000000');
INSERT INTO public.vendors (ord_id, app_id, title, labels, partners, id, documentation_labels, tags, app_template_version_id) VALUES ('vendor:ord.id', '4c63e3b2-3301-4796-bc95-9fb5b2780342', 'vendor-1', null, null, '2c23e3b2-3301-4796-bc95-9fb5b2780342', null, null, '54d9b48b-efea-4935-a7f3-c0ca61223206'); INSERT INTO public.vendors (ord_id, app_id, title, labels, partners, id, documentation_labels, tags, app_template_version_id) VALUES ('globalvendor:ord.id', null, 'global-vendor-1', null, null, '6c23e3b2-3301-4796-bc95-9fb5b2780342', null, null, '54d9b48b-efea-4935-a7f3-c0ca61223206');
INSERT INTO public.products (ord_id, app_id, title, short_description, vendor, parent, labels, correlation_ids, id, documentation_labels, tags, app_template_version_id, description) VALUES ('ord:product.id', '4c63e3b2-3301-4796-bc95-9fb5b2780342', 'product-1', 'short desc', 'vendor:ord.id', null, null, null, '1c23e3b2-3301-4796-bc95-9fb5b2780342', null, null, '54d9b48b-efea-4935-a7f3-c0ca61223206', 'desc');
INSERT INTO public.packages (id, ord_id, title, short_description, description, version, package_links, links, licence_type, tags, countries, labels, policy_level, app_id, custom_policy_level, vendor, part_of_products, line_of_business, industry, resource_hash, documentation_labels, support_info, app_template_version_id, runtime_restriction) VALUES ('fd5e9820-a8ae-4748-bf3f-049ef91804fa', ':package:manuallyAddedIntegrationDependencies:v1', 'Integration Dependencies package', 'Manually added package', 'This package contains manually added integration dependencies', '1.0.0', null, null, null, null, null, null, 'sap:core:v1', '4c63e3b2-3301-4796-bc95-9fb5b2780342', null, 'vendor:ord.id', '["ord:product.id"]', null, null, null, null, null, null, null);
INSERT INTO public.api_definitions (id, app_id, name, description, group_name, default_auth, version_value, version_deprecated, version_deprecated_since, version_for_removal, ord_id, short_description, system_instance_aware, api_protocol, tags, countries, links, api_resource_links, release_status, sunset_date, changelog_entries, labels, package_id, visibility, disabled, part_of_products, line_of_business, industry, ready, created_at, updated_at, deleted_at, error, implementation_standard, custom_implementation_standard, custom_implementation_standard_description, target_urls, extensible, successors, resource_hash, documentation_labels, policy_level, custom_policy_level, supported_use_cases, local_tenant_id, app_template_version_id, correlation_ids, direction, last_update, deprecation_date, responsible, usage) VALUES ('e710fee0-d954-476b-96d3-4e1b9e6007d1', '4c63e3b2-3301-4796-bc95-9fb5b2780342', 'bar-api-1', null, null, null, null, null, null, null, null, null, null, 'rest', '["tag1", "tag2"]', null, null, null, 'active', null, null, null, 'fd5e9820-a8ae-4748-bf3f-049ef91804fa', 'public', null, '["ord:product.id"]', null, null, true, '2024-03-05 13:39:30.737075', null, null, null, null, null, null, '["https://target.url"]', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); INSERT INTO public.api_definitions (id, app_id, name, description, group_name, default_auth, version_value, version_deprecated, version_deprecated_since, version_for_removal, ord_id, short_description, system_instance_aware, api_protocol, tags, countries, links, api_resource_links, release_status, sunset_date, changelog_entries, labels, package_id, visibility, disabled, part_of_products, line_of_business, industry, ready, created_at, updated_at, deleted_at, error, implementation_standard, custom_implementation_standard, custom_implementation_standard_description, target_urls, extensible, successors, resource_hash, documentation_labels, policy_level, custom_policy_level, supported_use_cases, local_tenant_id, app_template_version_id, correlation_ids, direction, last_update, deprecation_date, responsible, usage) VALUES ('349af461-f94f-45c4-b4df-0a97513a5211', '4c63e3b2-3301-4796-bc95-9fb5b2780342', 'foo-api-1', null, null, null, null, null, null, null, null, null, null, 'rest', '["tag1", "tag2"]', null, null, null, 'active', null, null, null, 'fd5e9820-a8ae-4748-bf3f-049ef91804fa', 'public', null, '["ord:product.id"]', null, null, true, '2024-03-05 13:40:01.554421', null, null, null, null, null, null, '["https://target.url"]', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
INSERT INTO public.bundle_references (api_def_id, event_def_id, bundle_id, api_def_url, id, is_default_bundle) VALUES ('e710fee0-d954-476b-96d3-4e1b9e6007d1', null, '96fbf863-93ad-4c59-9464-61753e212e77', 'https://target.url', 'e8cb92c5-e8bb-46b3-b0a4-7a15b9164ac1', null); INSERT INTO public.bundle_references (api_def_id, event_def_id, bundle_id, api_def_url, id, is_default_bundle) VALUES ('349af461-f94f-45c4-b4df-0a97513a5211', null, '96fbf863-93ad-4c59-9464-61753e212e77', 'https://target.url', 'f70ae64a-27a1-4b39-9dec-afb1349362a4', null);
INSERT INTO public.destinations (id, name, type, url, authentication, bundle_id, tenant_id, revision, formation_assignment_id, instance_id) VALUES ('22028605-5435-45b3-99bb-ae9a54cd9174', 'dest-foo', 'basic', 'http://test.com/v2', 'basic', '96fbf863-93ad-4c59-9464-61753e212e77', '3e64ebae-38b5-46a0-b1ed-9ccee153a0ae', '3e24ebae-38b5-46a0-b1ed-9ccee153a0ae', null, null);