or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdjdbc-container.mdjdbc-provider.mdr2dbc-support.md
tile.json

jdbc-container.mddocs/

JDBC Container API

The ClickHouseContainer class provides the primary API for creating and managing ClickHouse database containers with JDBC connectivity. It extends JdbcDatabaseContainer and provides ClickHouse-specific configuration options.

Key Information for Agents

Core Capabilities:

  • Container creation with Docker image specification
  • Connection information retrieval (JDBC URL, driver, credentials, database)
  • Credential configuration (username, password, database name)
  • URL parameter configuration for ClickHouse settings
  • Initialization script execution on container startup
  • Timeout configuration (startup and connection)
  • Container lifecycle management (start, stop, port mapping)
  • Container reuse support
  • Environment variable configuration

Key Methods:

  • Constructors: ClickHouseContainer(String dockerImageName), ClickHouseContainer(DockerImageName dockerImageName)
  • Connection info: getJdbcUrl(), getDriverClassName(), getUsername(), getPassword(), getDatabaseName(), getTestQueryString()
  • Configuration: withUsername(), withPassword(), withDatabaseName(), withUrlParam(), withInitScript(), withInitScripts(), withStartupTimeoutSeconds(), withConnectTimeoutSeconds(), withReuse(), withEnv()
  • Lifecycle: start(), stop(), getMappedPort(), getHost(), getLivenessCheckPortNumbers()

Default Behaviors:

  • Image must be specified in constructor (no default)
  • Default username: "test"
  • Default password: "test"
  • Default database: "default"
  • Default HTTP port: 8123 (mapped to random host port)
  • Default native port: 9000 (mapped to random host port)
  • Default startup timeout: 120 seconds
  • Default connection timeout: 120 seconds
  • Container reuse: Disabled by default
  • Driver detection: Automatic (checks com.clickhouse.jdbc.Driver first, then com.clickhouse.jdbc.ClickHouseDriver)

Threading Model:

  • Container instances are not thread-safe for concurrent modification
  • start() and stop() are blocking and should be called from a single thread
  • Multiple containers can run concurrently in separate instances
  • JDBC connections are independent of container lifecycle

Lifecycle:

  • Container must be started with start() before use
  • start() blocks until container is healthy
  • Initialization scripts execute after health check passes but before start() returns
  • Container must be stopped with stop() or use try-with-resources
  • Container data is ephemeral unless volumes are used

Exceptions:

  • IllegalArgumentException: Invalid parameters (null/empty image name, null/empty username/database, invalid timeout)
  • IllegalStateException: Methods called before start() or after stop(), multiple start() calls
  • ContainerLaunchException: Container fails to start (Docker issues, image pull failures, health check timeouts, script failures)
  • TimeoutException: Startup timeout exceeded
  • ClassNotFoundException: No JDBC driver found on classpath

Edge Cases:

  • Image name without tag defaults to latest (not recommended)
  • Invalid image names fail at start() time, not construction
  • Empty/null strings for username/database throw IllegalArgumentException
  • Special characters in credentials are URL-encoded
  • Multiple withUrlParam() calls with same name: last value wins
  • Missing script files cause ContainerLaunchException during start()
  • Empty scripts are allowed (no-op)
  • Very large scripts may exceed connection timeout
  • Very short timeouts (< 10 seconds) may cause false failures
  • Container reuse requires testcontainers.reuse.enable=true in properties
  • Reused containers may have stale data
  • Null key in withEnv() throws IllegalArgumentException
  • Null value in withEnv() sets variable to empty string
  • Environment variables override container defaults
  • Invalid port numbers throw IllegalArgumentException

Capabilities

Container Creation

Creates a new ClickHouse container instance with the specified Docker image.

/**
 * Create a ClickHouse container with a Docker image name string
 * @param dockerImageName Docker image name (e.g., "clickhouse/clickhouse-server:24.12-alpine")
 * @throws IllegalArgumentException if dockerImageName is null or empty
 */
public ClickHouseContainer(String dockerImageName);

/**
 * Create a ClickHouse container with a DockerImageName object
 * @param dockerImageName DockerImageName instance
 * @throws IllegalArgumentException if dockerImageName is null
 */
public ClickHouseContainer(DockerImageName dockerImageName);

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;
import org.testcontainers.utility.DockerImageName;

// Using string image name
ClickHouseContainer container1 = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine");

// Using DockerImageName
DockerImageName imageName = DockerImageName.parse("clickhouse/clickhouse-server:24.12-alpine");
ClickHouseContainer container2 = new ClickHouseContainer(imageName);

// Must call start() to launch the container
container1.start();

Edge Cases:

  • Image name without tag defaults to latest (not recommended for tests)
  • Invalid image names will fail at start() time, not construction time
  • Image pull failures are reported as ContainerLaunchException during start()
  • Null or empty image name throws IllegalArgumentException immediately

Connection Information

Get JDBC connection details for the running container. All methods throw IllegalStateException if called before start().

/**
 * Get the JDBC URL for connecting to the ClickHouse database
 * Format: jdbc:clickhouse://host:port/database
 * @return JDBC URL string
 * @throws IllegalStateException if container is not started
 */
public String getJdbcUrl();

/**
 * Get the JDBC driver class name
 * Automatically detects and returns the appropriate driver based on classpath availability
 * Priority: com.clickhouse.jdbc.Driver (new) > com.clickhouse.jdbc.ClickHouseDriver (legacy)
 * @return Driver class name
 * @throws IllegalStateException if container is not started
 * @throws ClassNotFoundException if no JDBC driver is found on classpath
 */
public String getDriverClassName();

/**
 * Get the configured username
 * @return Username for database authentication (default: "test")
 * @throws IllegalStateException if container is not started
 */
public String getUsername();

/**
 * Get the configured password
 * @return Password for database authentication (default: "test")
 * @throws IllegalStateException if container is not started
 */
public String getPassword();

/**
 * Get the configured database name
 * @return Database name (default: "default")
 * @throws IllegalStateException if container is not started
 */
public String getDatabaseName();

/**
 * Get the test query string used for health checks
 * @return Test query string ("SELECT 1")
 * @throws IllegalStateException if container is not started
 */
public String getTestQueryString();

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;
import java.sql.Connection;
import java.sql.DriverManager;

try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")) {
    clickhouse.start();

    // Get connection information
    String jdbcUrl = clickhouse.getJdbcUrl();
    // Returns: "jdbc:clickhouse://localhost:32768/default" (port varies)

    String username = clickhouse.getUsername(); // Returns: "test"
    String password = clickhouse.getPassword(); // Returns: "test"
    String databaseName = clickhouse.getDatabaseName(); // Returns: "default"
    String driverClass = clickhouse.getDriverClassName(); // Returns driver class name

    // Create JDBC connection
    try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
        // Execute queries...
    }
}

Error Handling:

// Wrong: calling before start()
ClickHouseContainer container = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine");
String url = container.getJdbcUrl(); // Throws IllegalStateException

// Correct: start first
container.start();
String url = container.getJdbcUrl(); // OK

Edge Cases:

  • All connection info methods throw IllegalStateException if called before start()
  • getDriverClassName() throws ClassNotFoundException if no driver is on classpath
  • JDBC URL format: jdbc:clickhouse://host:port/database
  • Port in URL is the mapped host port (random, retrieved via getMappedPort(8123))
  • Special characters in credentials are URL-encoded in JDBC URL

Credential Configuration

Configure custom database credentials using fluent builder methods. Methods can be called in any order and are chainable.

/**
 * Set custom username for database authentication
 * @param username Username to use (cannot be null or empty)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if username is null or empty
 */
public ClickHouseContainer withUsername(String username);

/**
 * Set custom password for database authentication
 * @param password Password to use (cannot be null)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if password is null
 */
public ClickHouseContainer withPassword(String password);

/**
 * Set custom database name
 * @param databaseName Database name to use (cannot be null or empty)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if databaseName is null or empty
 */
public ClickHouseContainer withDatabaseName(String databaseName);

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;

// Configure custom credentials
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withUsername("myuser")
        .withPassword("mypassword")
        .withDatabaseName("mydb")) {

    clickhouse.start();

    String jdbcUrl = clickhouse.getJdbcUrl();
    // Returns: "jdbc:clickhouse://localhost:32768/mydb"

    String username = clickhouse.getUsername(); // Returns: "myuser"
    String password = clickhouse.getPassword(); // Returns: "mypassword"
    String database = clickhouse.getDatabaseName(); // Returns: "mydb"
}

Edge Cases:

  • Empty strings for username/database name throw IllegalArgumentException
  • Null values throw IllegalArgumentException
  • Password can be empty string (not null)
  • Credentials are validated when container starts, not when set
  • Special characters in credentials are URL-encoded in JDBC URL
  • Methods are chainable and can be called in any order

URL Parameters

Add custom URL parameters to the JDBC connection string, useful for ClickHouse session settings and driver configuration.

/**
 * Add a URL parameter to the JDBC connection string
 * Parameters are appended to the JDBC URL as query parameters
 * @param paramName Parameter name (use "clickhouse_setting_" prefix for session settings)
 * @param paramValue Parameter value (will be URL-encoded)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if paramName or paramValue is null
 */
public ClickHouseContainer withUrlParam(String paramName, String paramValue);

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

// Configure ClickHouse session settings via URL parameters
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withUrlParam("clickhouse_setting_max_result_rows", "1000")
        .withUrlParam("clickhouse_setting_connect_timeout", "30")
        .withUrlParam("custom_param", "value")) {

    clickhouse.start();

    String jdbcUrl = clickhouse.getJdbcUrl();
    // Returns: "jdbc:clickhouse://localhost:32768/default?clickhouse_setting_max_result_rows=1000&clickhouse_setting_connect_timeout=30&custom_param=value"

    try (Connection conn = DriverManager.getConnection(jdbcUrl, clickhouse.getUsername(), clickhouse.getPassword());
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT value FROM system.settings WHERE name='max_result_rows'")) {
        rs.next();
        System.out.println("max_result_rows: " + rs.getInt(1)); // Prints: 1000
    }
}

Common ClickHouse Settings:

  • clickhouse_setting_max_result_rows: Maximum rows in result set
  • clickhouse_setting_max_execution_time: Query execution timeout in seconds
  • clickhouse_setting_connect_timeout: Connection timeout in seconds
  • clickhouse_setting_send_timeout: Send timeout in seconds
  • clickhouse_setting_receive_timeout: Receive timeout in seconds

Edge Cases:

  • Multiple calls to withUrlParam with same name: last value wins
  • Special characters in values are automatically URL-encoded
  • Null parameter names or values throw IllegalArgumentException
  • Parameters are appended to JDBC URL as query string
  • clickhouse_setting_* prefix is required for ClickHouse session settings

Initialization Scripts

Execute SQL scripts when the container starts, useful for setting up test schemas, tables, and initial data. Scripts are executed in order after the container is healthy but before start() returns.

/**
 * Set a single initialization script to execute on container startup
 * Replaces any previously set scripts
 * Script path is resolved from classpath (e.g., "init.sql" in src/test/resources)
 * @param initScriptPath Path to SQL script file (classpath resource)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if initScriptPath is null or empty
 */
public ClickHouseContainer withInitScript(String initScriptPath);

/**
 * Set multiple initialization scripts to execute on container startup in order
 * Replaces any previously set scripts
 * @param initScriptPaths Paths to SQL script files (classpath resources)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if initScriptPaths is null or contains null/empty paths
 */
public ClickHouseContainer withInitScripts(String... initScriptPaths);

/**
 * Set multiple initialization scripts from an iterable collection
 * Replaces any previously set scripts
 * @param initScriptPaths Iterable of paths to SQL script files
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if initScriptPaths is null or contains null/empty paths
 */
public ClickHouseContainer withInitScripts(Iterable<String> initScriptPaths);

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;
import java.util.Arrays;

// Single initialization script
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withInitScript("init.sql")) {
    clickhouse.start();
    // init.sql is executed before container is ready
}

// Multiple initialization scripts (executed in order)
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withInitScripts("schema.sql", "data.sql", "indexes.sql")) {
    clickhouse.start();
    // Scripts executed in order: schema.sql, then data.sql, then indexes.sql
}

// From a collection
Iterable<String> scripts = Arrays.asList("init1.sql", "init2.sql");
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withInitScripts(scripts)) {
    clickhouse.start();
}

Script Execution Details:

  • Scripts are executed sequentially in the order provided
  • Each script is executed as a single transaction (if supported by ClickHouse)
  • Script failures cause start() to throw ContainerLaunchException
  • Scripts are executed after health check passes but before start() returns
  • Script paths are resolved from classpath (typically src/test/resources)

Edge Cases:

  • Missing script files cause ContainerLaunchException during start()
  • Empty scripts are allowed (no-op)
  • Scripts with syntax errors cause ContainerLaunchException
  • Very large scripts may exceed connection timeout (increase with withConnectTimeoutSeconds())
  • Script paths must be valid classpath resources
  • Scripts are executed in order, so dependencies must be ordered correctly
  • Script execution happens synchronously during start()

Timeout Configuration

Configure startup and connection timeout values for the container. Timeouts are in seconds.

/**
 * Set startup timeout including image pull time
 * Includes time to pull image, create container, start container, and pass health check
 * @param startupTimeoutSeconds Timeout in seconds (default: 120, minimum: 1)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if timeout is less than 1
 */
public ClickHouseContainer withStartupTimeoutSeconds(int startupTimeoutSeconds);

/**
 * Set timeout for establishing initial database connection
 * Used for health checks and initialization script execution
 * @param connectTimeoutSeconds Timeout in seconds (default: 120, minimum: 1)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if timeout is less than 1
 */
public ClickHouseContainer withConnectTimeoutSeconds(int connectTimeoutSeconds);

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;

// Increase timeouts for slow environments
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withStartupTimeoutSeconds(300)    // 5 minutes for startup
        .withConnectTimeoutSeconds(180)) {  // 3 minutes for connection
    clickhouse.start();
}

// Decrease timeouts for faster failure detection
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withStartupTimeoutSeconds(30)) {  // Fail fast if container doesn't start quickly
    clickhouse.start();
}

Timeout Behavior:

  • Startup timeout includes: image pull, container creation, container start, health check
  • Connection timeout is used for: health check connection, initialization script execution
  • Timeout exceptions include details about what operation timed out
  • Very short timeouts (< 10 seconds) may cause false failures on slow systems
  • Timeout values must be at least 1 second

Edge Cases:

  • Timeout values less than 1 throw IllegalArgumentException
  • Startup timeout includes all phases (pull, create, start, health check)
  • Connection timeout is separate and used for database operations
  • Timeout exceptions provide detailed error messages
  • Very short timeouts may cause false failures in CI/CD environments

Container Lifecycle

Manage container lifecycle including starting, stopping, and getting port mappings. Lifecycle methods are not thread-safe.

/**
 * Start the container
 * Pulls the image if not present, creates the container, starts it, and waits until ready
 * Blocks until container is healthy or timeout occurs
 * @throws ContainerLaunchException if container fails to start
 * @throws TimeoutException if startup timeout is exceeded
 * @throws IllegalStateException if container is already started
 */
public void start();

/**
 * Stop the container
 * Stops and removes the container
 * Safe to call multiple times (idempotent)
 * @throws IllegalStateException if container was never started
 */
public void stop();

/**
 * Get the mapped port for a container port
 * Returns the host port that maps to the container port
 * @param originalPort Original container port (8123 for HTTP, 9000 for native)
 * @return Host port that maps to the container port
 * @throws IllegalStateException if container is not started
 * @throws IllegalArgumentException if originalPort is not exposed
 */
public Integer getMappedPort(int originalPort);

/**
 * Get the container host
 * Typically "localhost" but may vary in Docker networking configurations
 * @return Host address
 * @throws IllegalStateException if container is not started
 */
public String getHost();

/**
 * Get ports used for liveness checks
 * Returns set containing the HTTP port (8123)
 * @return Set containing the HTTP port
 * @throws IllegalStateException if container is not started
 */
public Set<Integer> getLivenessCheckPortNumbers();

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;

try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")) {
    // Start the container
    clickhouse.start();

    // Get mapped ports (8123 = HTTP port, 9000 = native port)
    Integer httpPort = clickhouse.getMappedPort(8123);
    // Returns: e.g., 32768 (dynamically assigned host port)

    Integer nativePort = clickhouse.getMappedPort(9000);
    // Returns: e.g., 32769

    String host = clickhouse.getHost(); // Returns: "localhost"

    // Manually construct connection URL if needed
    String customUrl = "jdbc:clickhouse://" + host + ":" + httpPort + "/default";

    // Stop is called automatically by try-with-resources
}

Lifecycle States:

  • Created: Container object created, not started
  • Starting: start() called, container is being created/started
  • Started: Container is running and healthy
  • Stopped: Container stopped, can be restarted
  • Closed: Container removed, cannot be restarted

Error Handling:

// Multiple start() calls
container.start();
container.start(); // Throws IllegalStateException

// Calling methods before start()
Integer port = container.getMappedPort(8123); // Throws IllegalStateException

// Invalid port
Integer port = container.getMappedPort(9999); // Throws IllegalArgumentException

Edge Cases:

  • start() throws IllegalStateException if already started
  • stop() is idempotent (safe to call multiple times)
  • stop() throws IllegalStateException if never started
  • All methods throw IllegalStateException if called before start()
  • getMappedPort() throws IllegalArgumentException for non-exposed ports
  • Ports are dynamically assigned and may vary between runs
  • Host is typically "localhost" but may vary in Docker networking

Container Reuse

Enable container reuse across test runs to improve performance. Requires testcontainers.reuse.enable=true in ~/.testcontainers.properties.

/**
 * Enable or disable container reuse
 * When enabled, container will be reused across test runs if configuration matches
 * Configuration matching includes: image, credentials, database name, init scripts
 * @param reuse True to enable reuse, false to disable
 * @return Self reference for method chaining
 */
public ClickHouseContainer withReuse(boolean reuse);

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;

// Enable container reuse for faster test execution
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withReuse(true)) {
    clickhouse.start();
    // Container will be reused if a matching container already exists
}

Reuse Behavior:

  • Containers are matched by: image name, username, password, database name, init scripts
  • Reused containers are not stopped when test completes
  • Reused containers persist data between test runs
  • Container reuse requires testcontainers.reuse.enable=true in ~/.testcontainers.properties
  • If no matching container exists, a new one is created

Edge Cases:

  • Reuse enabled but no matching container: new container is created
  • Reuse enabled but property not set: reuse is silently ignored, new container created
  • Reused containers may have stale data from previous test runs
  • Container matching is based on exact configuration match
  • Reused containers persist across JVM restarts (if Docker daemon persists)

Environment Variables

Set custom environment variables for the container. Environment variables are set before container starts.

/**
 * Set an environment variable in the container
 * Environment variables are available to the ClickHouse process
 * @param key Environment variable name (cannot be null)
 * @param value Environment variable value (can be null, sets to empty string)
 * @return Self reference for method chaining
 * @throws IllegalArgumentException if key is null
 */
public ClickHouseContainer withEnv(String key, String value);

Usage Examples:

import org.testcontainers.clickhouse.ClickHouseContainer;

// Set custom environment variables
try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
        .withEnv("CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT", "1")
        .withEnv("TZ", "UTC")
        .withEnv("CLICKHOUSE_LOG_LEVEL", "trace")) {
    clickhouse.start();
}

Common Environment Variables:

  • CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: Enable access management (1 = enabled)
  • TZ: Timezone (e.g., "UTC", "America/New_York")
  • CLICKHOUSE_LOG_LEVEL: Logging level (trace, debug, information, warning, error)
  • CLICKHOUSE_USER_FILES_PATH: Path to user configuration files

Edge Cases:

  • Null key throws IllegalArgumentException
  • Null value sets environment variable to empty string
  • Environment variables override container defaults (e.g., CLICKHOUSE_USER, CLICKHOUSE_PASSWORD)
  • Environment variables are set before container starts, cannot be changed after
  • Multiple calls with same key: last value wins

Complete Example

import org.testcontainers.clickhouse.ClickHouseContainer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ClickHouseTest {
    public void testClickHouse() throws Exception {
        // Create container with full configuration
        try (ClickHouseContainer clickhouse = new ClickHouseContainer("clickhouse/clickhouse-server:24.12-alpine")
                .withUsername("testuser")
                .withPassword("testpass")
                .withDatabaseName("testdb")
                .withUrlParam("clickhouse_setting_max_execution_time", "60")
                .withInitScript("schema.sql")
                .withStartupTimeoutSeconds(180)
                .withReuse(true)
                .withEnv("TZ", "UTC")) {

            // Start container
            clickhouse.start();

            // Get connection details
            String jdbcUrl = clickhouse.getJdbcUrl();
            String username = clickhouse.getUsername();
            String password = clickhouse.getPassword();

            // Connect and execute queries
            try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
                // Create table
                try (PreparedStatement stmt = conn.prepareStatement(
                        "CREATE TABLE IF NOT EXISTS users (id UInt32, name String) ENGINE = MergeTree() ORDER BY id")) {
                    stmt.execute();
                }

                // Insert data
                try (PreparedStatement stmt = conn.prepareStatement(
                        "INSERT INTO users (id, name) VALUES (?, ?)")) {
                    stmt.setInt(1, 1);
                    stmt.setString(2, "Alice");
                    stmt.execute();
                }

                // Query data
                try (PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
                     ResultSet rs = stmt.executeQuery()) {
                    stmt.setInt(1, 1);
                    if (rs.next()) {
                        System.out.println("User: " + rs.getString("name"));
                    }
                }
            } catch (SQLException e) {
                System.err.println("Database error: " + e.getMessage());
                throw e;
            }
        } catch (ContainerLaunchException e) {
            System.err.println("Container failed to start: " + e.getMessage());
            throw e;
        }
    }
}

Inherited Methods from JdbcDatabaseContainer

ClickHouseContainer extends JdbcDatabaseContainer, which provides additional methods:

  • getJdbcUrl(): Returns JDBC URL (overridden by ClickHouseContainer)
  • getDriverClassName(): Returns driver class name (overridden by ClickHouseContainer)
  • getTestQueryString(): Returns test query (overridden by ClickHouseContainer)
  • getDatabaseName(): Returns database name (overridden by ClickHouseContainer)
  • getUsername(): Returns username (overridden by ClickHouseContainer)
  • getPassword(): Returns password (overridden by ClickHouseContainer)
  • waitingFor(WaitStrategy): Set custom wait strategy
  • withLogConsumer(Consumer<OutputFrame>): Add log consumer
  • withImagePullPolicy(PullPolicy): Set image pull policy
  • withNetwork(Network): Set Docker network
  • withNetworkMode(String): Set network mode
  • withNetworkAliases(String...): Add network aliases
  • withExposedPorts(Integer...): Expose additional ports
  • withCreateContainerCmdModifier(Consumer<CreateContainerCmd>): Modify container creation command
  • withCommand(String...): Override container command
  • withWorkingDirectory(String): Set working directory
  • withCopyFileToContainer(Transferable, String): Copy files to container
  • withCopyToContainer(Transferable, String): Copy files to container
  • execInContainer(String...): Execute commands in container
  • getContainerId(): Get container ID
  • getContainerInfo(): Get container info
  • getDockerImageName(): Get Docker image name
  • isRunning(): Check if container is running
  • isCreated(): Check if container is created
  • isHealthy(): Check if container is healthy

All inherited methods follow the same error handling patterns: throw IllegalStateException if called before start(), throw IllegalArgumentException for invalid parameters.