on ‎2021 Aug 11 1:19 PM
Dear Experts,
I'm getting the following error, but I'm in trouble because I don't know how to deal with it ...
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
[Handler dispath failed; nested exception is java.lang.NoSuchMethodError;
'com.sap.cloud.sdk.datamodel.odata.client.expression.FieldUntyped com.sap.cloud.sdk.datamodel.odata.cli
ent.expression.FieldReference.ofPath(java.lang.Striong[])'] with root cause
Timing:
This error is occurring in the Read process of the @On event. Correctly, "remote.run (selectQuery);" that is executed inside the Read process
There was an error in.
I'm not familiar with Java, so I'd appreciate it if you could tell me a little more about how to do it.
Regards,
rinn.
Request clarification before answering.
This is most likely a dependency issue. It seems like you are referencing a Cloud SDK version that is not compatible with the CAP Java version you are using. Please have a look at our public sample which always shows our recommended version combination: https://github.com/SAP-samples/cloud-cap-samples-java/blob/main/pom.xml#L19-L21
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sorry for my late reply.
I was able to solve the local error here!
However, there is another problem.
First, the data cannot be acquired. 0 results will be returned as a search result ...
Second, I get an error in the deployed application. The content was logged as "Caused by: com.sap.cds.CdsDataStoreException: Error executing the statement".
If you like, I would appreciate your advice on this as well ...
By the way, the URL you are referring to is here.
Thank you for your reply. Attach the error log. I was checking and thought, but is there a table in the DB? Was also seen. Since the attached URL refers to S / 4 (On Premise) data, I have not added the table to the DB on HANA Cloud. Is this necessary? I'm sorry to ask you various questions ...
CAP by default always try to read data from the Database using the PersistenceService. This is also what happens in your case and runs into an error as the database table is not available. If you want to read the data from somewhere else (e.g. the S/4 system) you need to explicitly forward the query to the S/4 system. You might want to look into Remote Services for this: https://cap.cloud.sap/docs/java/remote-services
Thank you for posting the link. I tried the contents of the remote service of the link.
However, there was no change in the error. (Contents that require Persistence Service) What else is missing?
The following is the contents of each file. (Pom.xml has been added as described in the link.)
application.yaml
---
spring:
config.activate.on-profile: default
datasource:
url: "jdbc:sqlite:file::memory:?cache=shared"
driver-class-name: org.sqlite.JDBC
hikari:
maximum-pool-size: 1
sql:
init:
mode: always
cds:
application.services:
- name: "OnPremiseService"
model: "Entity1_SRV"
remote.services:
- name: "Entity1_SRV"
destination:
name: "dest"
type: "odata-v2"
suffix: "/sap/opu/odata/sap"
---
spring:
config.activate.on-profile: cloud
cds:
remote.services:
- name: "Entity1_SRV"
destination:
name: "dest"
type: "odata-v2"
suffix: "/sap/opu/odata/sap"
OnPremiseService.java
package com.sap.cap.productsservice.handlers;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.sap.cds.services.handler.annotations.ServiceName;
import com.sap.cds.services.handler.annotations.On;
import com.sap.cds.services.cds.CdsReadEventContext;
import com.sap.cds.services.handler.EventHandler;
import com.sap.cds.Result;
import com.sap.cds.ql.Select;
import com.sap.cds.ql.cqn.CqnSelect;
import com.sap.cds.services.cds.CqnService;
import com.sap.cds.services.cds.CdsService;
import cds.gen.Entity1_srv.*;
@Component
@ServiceName("OnPremiseService")
public class OnPremiseService implements EventHandler {
@Autowired
@Qualifier(Entity1Srv_.CDS_NAME)
CqnService remote1;
@On(event = CdsService.EVENT_READ, entity = Entity1_.CDS_NAME)
public void onRead(CdsReadEventContext context) {
CqnSelect selectQuery = Select.from(Entity1_.CDS_NAME);
Result result = remote1.run(selectQuery);
context.setResult(result);
}
}
Thank you.
Pom(root) are attached below.
The error log and Pom.xml (srv) did not fit, so I will attach it as text.
Pom.xml(root)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">;
<modelVersion>4.0.0</modelVersion>
<groupId>com.sap.cap</groupId>
<artifactId>capforjavaapp-parent</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<name>capforjavaapp parent</name>
<properties>
<!-- OUR VERSION -->
<revision>1.0.0-SNAPSHOT</revision>
<!-- DEPENDENCIES VERSION -->
<jdk.version>1.8</jdk.version>
<cds.services.version>1.17.0</cds.services.version>
<spring.boot.version>2.5.2</spring.boot.version>
<cloud.sdk.version>3.46.0</cloud.sdk.version>
<node.url>https://nodejs.org/dist/</node.url>
</properties>
<modules>
<module>srv</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- CDS SERVICES -->
<dependency>
<groupId>com.sap.cds</groupId>
<artifactId>cds-services-bom</artifactId>
<version>${cds.services.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SPRING BOOT -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- CLOUD SDK -->
<dependency>
<groupId>com.sap.cloud.sdk</groupId>
<artifactId>sdk-bom</artifactId>
<version>${cloud.sdk.version}</version >
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- JAVA VERSION -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<!-- MAKE SPRING BOOT PLUGIN RUNNABLE FROM ROOT -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<!-- POM FLATTENING FOR CI FRIENDLY VERSIONS -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.2.5</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- PROJECT STRUCTURE CHECKS -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>Project Structure Checks</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>3.5.0</version>
</requireMavenVersion>
<requireJavaVersion>
<version>${jdk.version}</version>
</requireJavaVersion>
<reactorModuleConvergence />
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Thanks for the details. Everything looks fine in there. From the error stacktrace I can see however that your custom event handler that you implemented above that forwards the CQN statement to the remote service is not triggered.
Is the event handler in the same package or a sub-package as the Spring Boot Application.java class?
If not, the event handler will not be found during startup by Spring Boots automatic component scan.
Please move the event handler in that case to such a package.
If you think everything is correct and it still doesn't work, please provide the startup logs of the application.
I would like to check if we can see that the event handler is being detected in these logs.
The folder structure looks also fine. The logs you attached unfortunately don't show the application startup.
If you test the application in the cloud please run "cf restart <appname>" and provide the recent logs afterwards.
If you start the application locally, please simply provide the output that it generates when starting.
Thank you for making sure. I uploaded the source to github. However, due to the nature of the project, some modifications and deletions have been made. * S / 4 (On-Premise) connection related, etc.
If you have any questions, please let us know.
Thanks for sharing. I finally figured out why the request doesn't go into your event handler. The reason is that your event handler for "OnPremiseService" register on entities from "Entity1_SRV" by using the entity interfaces from that service (see here and here). However "OnPremiseService" is not using the "Entity1_SRV", but has its own model definition "OnPremiseService" (see here). Therefore you should also use the entities from that definition to register event handlers, e.g. by changing "import cds.gen.entity1_srv.*;" to "import cds.gen.onpremiseservice.*"
An alternative would be to create the "OnPremiseService" with the model definition of "Entity1_SRV", as you did for the "OnPreService" in the default profile (see here)
Does the method I modified fit in below?
1. changing "import cds.gen.entity1_srv.*;" to "import cds.gen.onpremiseservice.*"
2. An alternative would be to create the "OnPremiseService" with the model definition of "Entity1_SRV", as you did for the "OnPreService" in the default profile
I tried pattern 1.
But now I get a different error ...

When I checked the error log, the description of "ErrorLog3.txt" was repeated.
Perhaps the following content is repeated ??
Result result = remote1.run(selectQuery);
Is this error caused by the wrong way of dealing with me? Or is this another issue?
PS: I couldn't add comments all together, so I'm sorry it's difficult to read by dividing it ...
You shouldn't have changed the name of the injected service to "OnPremiseService" as well.
Basically @Qualifier(Entity1Srv_.CDS_NAME) still needs to be the qualifier of the remote1 variable you autowire.
With the current code the OnPremiseService is basically delegating the query to itself, which creates an infinite recursion that will result in a StackOverflowError. However you want to delegate the query from the OnPremiseService to the Entity1_SRV you defined as a RemoteService.
Please see the attached file: onpremiseservicejava-fixed.txt
Thank you for modifying the file.
Is the correction only for "@Qualifier"?
This is the only one. There seems to be no error in particular, but I could not get the data ...
There is a correction in the contents of the source, but there are the following differences.
Entity1_CDS_NAME (onpremiseservice) => String CDS_NAME = "OnPremiseService.ENTITY1"
Entity1_CDS_NAME (entity1_srv) => String CDS_NAME = "ENTITY1_SRV.ENTITY1"For the time being, I will attach the log of execution and restart.
Thank you for the information.
Added to "application.yaml".
Here is the log.
Thank you for your confirmation.
Sorry for my late reply. It means that it is sent normally.
Does that mean there's a problem with the backend ...
Let's check the endpoint.
However, due to various reasons, it is not possible to check immediately, so when you are ready to check, I will check this area!
I am reluctant to confirm the correct result, but thank you for your kind guidance.
We would be grateful if you could cooperate in the event of something happening.
Thank you very much.
| User | Count |
|---|---|
| 9 | |
| 5 | |
| 5 | |
| 4 | |
| 4 | |
| 2 | |
| 2 | |
| 2 | |
| 2 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.