Skip to content

fix(connector): fix Oracle database connection URL build and password…#509

Open
tfgzs wants to merge 1 commit intospring-ai-alibaba:mainfrom
tfgzs:fix/oracle-connection-issues
Open

fix(connector): fix Oracle database connection URL build and password…#509
tfgzs wants to merge 1 commit intospring-ai-alibaba:mainfrom
tfgzs:fix/oracle-connection-issues

Conversation

@tfgzs
Copy link
Copy Markdown

@tfgzs tfgzs commented Apr 17, 2026

Fix Oracle Database Connection Issues

📖 Summary

Fixed two critical bugs preventing Oracle database connections from working:

  1. Invalid JDBC URL construction - Schema name incorrectly included in connection URL
  2. Password field serialization - Password could not be saved due to @JsonIgnore annotation

🐛 Problems Fixed

Issue 1: Oracle JDBC URL Build Error

Symptom:

Failed to get database connection after 3 attempts, 
URL: jdbc:oracle:thin:@localhost:3306/BOSNDS3|BOSNDS3_ADMIN

Root Cause:

  • The databaseName field stores format: serviceName|schemaName (e.g., BOSNDS3|BOSNDS3_ADMIN)
  • OracleDatasourceTypeHandler.buildConnectionUrl() directly used the entire field
  • Generated invalid JDBC URL with schema name included

Solution:
Extract only the serviceName part (before |) when building the JDBC URL, while preserving the full field for schema extraction later.


Issue 2: Password Field Cannot Be Saved

Symptom:

ORA-01005: null password given; logon denied

Root Cause:

  • Datasource.password field used @JsonIgnore annotation
  • This causes bidirectional ignore:
    • ❌ Password not returned to frontend (correct - security)
    • ❌ Password not received from frontend (bug - prevents saving)
  • Users couldn't save passwords when creating/editing datasources

Solution:
Changed from @JsonIgnore to @JsonProperty(access = JsonProperty.Access.WRITE_ONLY):

  • ✅ Accepts password from frontend requests (input)
  • ✅ Does not expose password in API responses (security)

🔧 Changes Made

1. OracleDatasourceTypeHandler.java

File: data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/service/datasource/handler/impl/OracleDatasourceTypeHandler.java

// Before:
return String.format("jdbc:oracle:thin:@%s:%d/%s", 
    datasource.getHost(), datasource.getPort(),
    datasource.getDatabaseName()); // ❌ Includes "serviceName|schemaName"

// After:
String databaseName = datasource.getDatabaseName();
String serviceName = databaseName;
if (databaseName != null && databaseName.contains("|")) {
    serviceName = databaseName.split("\\|")[0]; // ✅ Extract only serviceName
}
return String.format("jdbc:oracle:thin:@%s:%d/%s", 
    datasource.getHost(), datasource.getPort(), serviceName);

2. Datasource.java

File: data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/entity/Datasource.java

// Before:
@JsonIgnore
private String password; // ❌ Bidirectional ignore

// After:
/**
 * Password field is only writable (input only).
 * It will not be returned in API responses for security reasons,
 * but can be received from API requests.
 */
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password; // ✅ Write-only: accepts input, hides output

3. DatasourceServiceImpl.java

File: data-agent-management/src/main/java/com/alibaba/cloud/ai/dataagent/service/datasource/impl/DatasourceServiceImpl.java

Added password validation before connection test:

// Validate password is not empty
if (datasource.getPassword() == null || datasource.getPassword().trim().isEmpty()) {
    log.error("Password is empty for datasource: {}", datasource.getName());
    return false;
}

✅ How to Test

Test Oracle Connection

  1. Create or edit an Oracle datasource
  2. Fill in connection details:
    • Host: localhost (or your Oracle host)
    • Port: 1521 (Oracle default port)
    • Database Name: serviceName|schemaName (e.g., BOSNDS3|BOSNDS3_ADMIN)
    • Username: Your Oracle username
    • Password: Your Oracle password
  3. Click "Test Connection"
  4. Should return success ✅

Verify Password Security

  1. Create/edit datasource with password
  2. Save the datasource
  3. Fetch the datasource list via API
  4. Verify password field is not present in response ✅
  5. Edit the datasource again
  6. Re-enter password and save
  7. Password should be updated successfully ✅

📝 Special Notes

For Reviewers

  1. Security Consideration: The @JsonProperty(WRITE_ONLY) approach is the standard Jackson pattern for password fields. It ensures:

    • Passwords can be submitted via API
    • Passwords are never exposed in API responses
    • Better than @JsonIgnore which prevents both operations
  2. Backward Compatibility:

    • Existing datasources will need to have their passwords re-entered (since they weren't saved before)
    • No database schema changes required
  3. Oracle URL Format:

    • Standard format: jdbc:oracle:thin:@host:port/serviceName
    • Schema is used separately in queries, not in connection URL
    • This aligns with how PostgreSQL handles schema

Testing Checklist

  • Oracle datasource creation works
  • Oracle datasource edit works
  • Oracle connection test succeeds
  • Password not exposed in API responses
  • Password can be saved and updated
  • Other datasource types (MySQL, PostgreSQL) still work correctly

🔗 Related Issues

Fixes connection errors:

  • ORA-01005: null password given; logon denied
  • GetConnectionTimeoutException with invalid Oracle URL format

📚 Documentation References

… serialization

- Fix Oracle JDBC URL construction by extracting serviceName from databaseName field
  (format: 'serviceName|schemaName' -> use only 'serviceName' for URL)
- Change password field from @JsonIgnore to @JsonProperty(WRITE_ONLY)
  to allow receiving password from frontend while not exposing it in responses
- Add password validation before connection test to fail fast with clear error

Fixes Oracle connection issues:
- ORA-01005: null password given; logon denied
- Invalid JDBC URL with schema name included
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

Successfully merging this pull request may close these issues.

1 participant