skip to Main Content

I am trying to setup a simple JDBC client to talk with a database in Ballerina.

However the "compile" ( VSCode ) error that is shown says:

invalid remote method call: expected a client object, but found (ballerinax/java.jdbc:1.7.0:Client|ballerina/sql:1.7.1:Error)(BCE2421)

Here is my full source code:

import ballerinax/java.jdbc;
import ballerina/sql;

public type User record {|
    int id?;
    string name;
    string username;
    string email;
    int? client_id;
|};

configurable string USER = ?;
configurable string PASSWORD = ?;
configurable string HOST = ?;
configurable int PORT = ?;
configurable string DATABASE = ?;


final jdbc:Client|sql:Error dbClient = new (
    url="", user=USER, password=PASSWORD
);

isolated function getUser(int id) returns User|error {
    sql:ParameterizedQuery query = `select * from users where ${id} = ?`;
    User user = dbClient->query(query);  // <--- THIS IS THE LINE THAT SHOWS ERROR
    return user;
}

2

Answers


  1. This is because of Ballerina Error Handling is different from other languages, For more details on error handling see Ballerina By Example: Error Handling.

    To look into this specific case. When invoking getUser() function dbClient may be either jdbc:Client or sql:Error. You can call the remote method query() only if the variable is of type jdbc:Client. You should narrow the type of the dbClient before the remote method is invoked.

    if dbClient is error {
        // handle the error
    } else {
        // Type of `dbClient` will be `jdbc:Client` here.
        sql:ExecutionResult result = 
                    check dbClient->execute(`...`);
    }
    

    Alternatively, you can use check keyword to narrow the type as sql:Error is an error type in Ballerina.

    final jdbc:Client|sql:Error dbClient = check new (
        url="", user=USER, password=PASSWORD
    );
    

    For more details on handling errors with check expression see Ballerina By Example: Check Expression.

    Login or Signup to reply.
  2. Changing the isolated function as follows worked for me. I think due to the error handling of ballerina you should either return the error so that the needed type is left or otherwise you should use the ‘check’ to do the same.

    isolated function getUser(int id) returns User|string {
      sql:ParameterizedQuery query = `select * from users where ${id} = ?`;
    
      jdbc:Client|sql:Error dbClient = new (
      url = "", user = USER, password = PASSWORD
      );
    
      if (dbClient is sql:Error) {
          return "Error occurred while retrieving user";
      }
      else if (dbClient is jdbc:Client) {
        sql:ExecutionResult|sql:Error result = dbClient->execute(query);
        if (result is sql:Error) {
            return "Error occurred while retrieving user";
        }
        else if (result is sql:ExecutionResult) {
            User user = {id, name: "", username: "", email: "", client_id: id};
            // associate the result to the user record according to the result you retrieved from the database in the above line
            return user;
        }
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search