Solve connection errors, resource leaks, and performance problems like a pro.
JDBC is powerful but comes with pitfalls. This guide tackles frequent errors and their fixes, helping you debug faster and write robust code.
Table of Contents
1. Connection Issues
Error: “No suitable driver found”
Cause:
- JDBC driver JAR not in the classpath.
- Incorrect connection URL syntax.
Solution:
- Add the driver JAR to your project (e.g.,
mysql-connector-java
). - Verify the URL format:
// MySQL Example
String url = "jdbc:mysql://localhost:3306/mydb";
Error: “Connection refused”
Cause:
- Database server not running.
- Firewall blocking port (e.g., MySQL’s default port 3306).
Solution:
- Start the database service (e.g.,
sudo systemctl start mysql
). - Check connectivity using tools like
telnet
:
telnet localhost 3306
2. Resource Leaks
Error: Too many open connections
Cause: Not closing Connection
, Statement
, or ResultSet
.
Solution: Use try-with-resources
to auto-close:
try (Connection conn = DriverManager.getConnection(...);
PreparedStatement pstmt = conn.prepareStatement(...);
ResultSet rs = pstmt.executeQuery()) {
// Use resources
} // Auto-closed here
3. Transaction Locking/Timeout
Error: “Lock wait timeout exceeded”
Cause: Long-running transactions holding locks.
Solution:
- Keep transactions short.
- Set isolation levels appropriately:
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
4. SQL Syntax Errors
Error: “You have an error in your SQL syntax”
Cause: Typos or invalid SQL in queries.
Solution:
- Print the SQL string before execution for debugging.
- Test queries directly in a database client (e.g., MySQL Workbench).
5. NullPointerException in ResultSet
Cause: Accessing nullable columns without checks.
Solution: Use wasNull()
to handle NULL
values:
String email = rs.getString("email");
if (rs.wasNull()) {
email = "N/A";
}
6. Performance Bottlenecks
Problem: Slow batch inserts
Solution:
- Use
addBatch()
andexecuteBatch()
. - For MySQL, add rewriteBatchedStatements
=true
to the URL:
String url = "jdbc:mysql://localhost:3306/mydb?rewriteBatchedStatements=true";
7. SQL Injection Vulnerabilities
Risk: Using Statement
with user input.
Bad Practice:
String sql = "SELECT * FROM users WHERE name = '" + input + "'";
Solution: Always use PreparedStatement
:
String sql = "SELECT * FROM users WHERE name = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, input);
8. Debugging Tips
Enable JDBC Logging
Add these properties to your database URL for MySQL:
String url = "jdbc:mysql://localhost/mydb?logger=Slf4JLogger&profileSQL=true";
Check Database Logs
- MySQL:
/var/log/mysql/error.log
- PostgreSQL:
/var/log/postgresql/postgresql-XX-main.log
Common Errors & Fixes Cheat Sheet
Error | Solution |
---|---|
java.sql.SQLException: Access denied | Verify username/password. Grant database privileges. |
ResultSet is closed | Avoid closing Statement before processing ResultSet . |
Data truncated for column | Check column data types and lengths. |
Communications link failure | Test network connectivity; restart the database. |
Preventive Best Practices
- Use Connection Pooling: Prevents leaks and improves performance.
- Validate Inputs: Sanitize data types and lengths.
- Test Queries Separately: Debug SQL in tools like DBeaver before coding.
Summary
- Connection Issues: Verify drivers, URLs, and server status.
- Resource Leaks: Use
try-with-resources
religiously. - Performance: Batch operations and connection pooling.
Next Up: JDBC Interview Questions – Prepare for common technical screenings!