CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-typesafe-play--play-jdbc-2-11

Play Framework JDBC support library providing database access, connection pooling, and database configuration management for Play applications.

Pending
Overview
Eval results
Files

database-configuration.mddocs/

Database Configuration

Type-safe configuration system supporting multiple databases, JNDI, environment-specific settings, and various database connection formats.

Capabilities

DatabaseConfig Case Class

Type-safe holder for database configuration parameters.

case class DatabaseConfig(
  driver: Option[String],
  url: Option[String],
  username: Option[String], 
  password: Option[String],
  jndiName: Option[String]
)

Usage Examples:

import play.api.db.DatabaseConfig

// Minimal configuration
val basicConfig = DatabaseConfig(
  driver = Some("org.h2.Driver"),
  url = Some("jdbc:h2:mem:test"),
  username = None,
  password = None,
  jndiName = None
)

// Full configuration
val prodConfig = DatabaseConfig(
  driver = Some("org.postgresql.Driver"),
  url = Some("jdbc:postgresql://db.example.com:5432/production"),
  username = Some("app_user"),
  password = Some("secure_password"),
  jndiName = Some("java:comp/env/jdbc/ProductionDB")
)

// JNDI-only configuration
val jndiConfig = DatabaseConfig(
  driver = None,
  url = None,
  username = None,
  password = None, 
  jndiName = Some("java:comp/env/jdbc/ExternalDB")
)

DatabaseConfig Factory Method

Factory method for creating DatabaseConfig from Play Configuration.

object DatabaseConfig {
  def fromConfig(config: Configuration, environment: Environment): DatabaseConfig
}

Usage Examples:

import play.api.db.DatabaseConfig
import play.api.{Configuration, Environment}
import com.typesafe.config.ConfigFactory

val configData = ConfigFactory.parseString("""
  driver = "org.postgresql.Driver"
  url = "postgres://user:pass@localhost/mydb"
  username = "override_user"
  logSql = true
""")

val config = Configuration(configData)
val environment = Environment.simple()

val dbConfig = DatabaseConfig.fromConfig(config, environment)
// Results in:
// DatabaseConfig(
//   driver = Some("org.postgresql.Driver"),
//   url = Some("jdbc:postgresql://localhost/mydb"),
//   username = Some("override_user"), // overrides URL credential
//   password = Some("pass"), // extracted from URL
//   jndiName = None
// )

Configuration Sources

Application Configuration

Primary configuration through application.conf:

# Single database configuration
db.default {
  driver = "org.postgresql.Driver"
  url = "jdbc:postgresql://localhost/myapp"
  username = "dbuser"
  password = "dbpass"
  
  # Connection pool settings
  hikaricp {
    minimumIdle = 5
    maximumPoolSize = 20
  }
  
  # Optional settings
  jndiName = "java:comp/env/jdbc/MyAppDB"
  logSql = false
}

# Multiple database configuration  
db {
  users {
    driver = "org.postgresql.Driver"
    url = "jdbc:postgresql://users-db:5432/users"
    username = ${DB_USER}
    password = ${DB_PASS}
  }
  
  cache {
    driver = "org.h2.Driver"
    url = "jdbc:h2:mem:cache;DB_CLOSE_DELAY=-1"
  }
  
  analytics {
    driver = "org.postgresql.Driver"
    url = "jdbc:postgresql://analytics:5432/warehouse"
    username = "analyst"
    password = "readonly"
    hikaricp.readOnly = true
  }
}

Environment Variables

Support for environment variable substitution:

db.default {
  driver = "org.postgresql.Driver"
  url = ${DATABASE_URL}
  username = ${DB_USERNAME}
  password = ${DB_PASSWORD}
  
  hikaricp {
    maximumPoolSize = ${?DB_POOL_SIZE} # Optional with default fallback
  }
}

System Properties

Configuration can be overridden via system properties:

# Command line system properties
java -Ddb.default.url="jdbc:postgresql://prod-db/myapp" \
     -Ddb.default.username="prod_user" \
     -Ddb.default.password="prod_pass" \
     -jar myapp.jar

URL Formats and Shortcuts

Standard JDBC URLs

db.default {
  driver = "org.postgresql.Driver"
  url = "jdbc:postgresql://localhost:5432/myapp?ssl=true&sslmode=require"
  username = "user"
  password = "pass"
}

Shortcut URL Formats

PostgreSQL Shortcut:

db.default {
  url = "postgres://user:pass@localhost:5432/myapp"
  # Automatically converts to: jdbc:postgresql://localhost:5432/myapp
  # Credentials automatically extracted
}

MySQL Shortcut:

db.default {
  url = "mysql://user:pass@localhost:3306/myapp"
  # Automatically converts to: jdbc:mysql://localhost:3306/myapp?useUnicode=yes&characterEncoding=UTF-8&connectionCollation=utf8_general_ci
  # Credentials automatically extracted
}

H2 Development Enhancement:

db.default {
  url = "jdbc:h2:mem:testdb"
  # In development mode, automatically becomes: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
}

Credential Handling

Credentials can be specified in multiple ways with precedence order:

  1. Explicit username/password configuration (highest precedence)
  2. URL-embedded credentials
  3. Environment variables
  4. System properties
db.default {
  url = "postgres://url_user:url_pass@localhost/myapp"
  username = "config_user"    # This overrides URL credential
  password = "config_pass"    # This overrides URL credential
  # Final result: config_user/config_pass is used
}

JNDI Configuration

JNDI Data Source

Configure database to use existing JNDI data source:

db.default {
  jndiName = "java:comp/env/jdbc/MyAppDB"
  # No driver, url, username, password needed
}

JNDI Binding

Bind created data source to JNDI name:

db.default {
  driver = "org.postgresql.Driver"
  url = "jdbc:postgresql://localhost/myapp"
  username = "user"
  password = "pass"
  jndiName = "java:comp/env/jdbc/MyAppDB"  # Binds data source to this JNDI name
}

Environment-Specific Configuration

Development Configuration

# conf/application.conf
db.default {
  driver = "org.h2.Driver"
  url = "jdbc:h2:mem:devdb;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false"
  username = "sa"
  password = ""
  
  hikaricp {
    minimumIdle = 1
    maximumPoolSize = 5
  }
  
  logSql = true  # Enable SQL logging in development
}

Production Configuration

# conf/application.prod.conf  
include "application.conf"

db.default {
  driver = "org.postgresql.Driver"
  url = ${DATABASE_URL}
  username = ${DB_USERNAME} 
  password = ${DB_PASSWORD}
  
  hikaricp {
    minimumIdle = 10
    maximumPoolSize = 30
    connectionTimeout = 30 seconds
    idleTimeout = 10 minutes
    maxLifetime = 30 minutes
    leakDetectionThreshold = 60 seconds
  }
  
  logSql = false  # Disable SQL logging in production
}

Test Configuration

# conf/application.test.conf
include "application.conf"

db.default {
  driver = "org.h2.Driver"
  url = "jdbc:h2:mem:testdb;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false"
  username = "sa"
  password = ""
}

Configuration Validation

Required vs Optional Fields

  • driver: Required unless using JNDI
  • url: Required unless using JNDI
  • username: Optional (can be embedded in URL)
  • password: Optional (can be embedded in URL)
  • jndiName: Optional (for JNDI binding or lookup)

Configuration Errors

Common configuration errors and solutions:

// Missing driver
db.default {
  url = "jdbc:postgresql://localhost/myapp"
  # Error: Driver not specified and cannot be inferred
}

// Invalid URL format
db.default {
  driver = "org.postgresql.Driver"
  url = "invalid-url"  
  # Error: Invalid JDBC URL format
}

// Conflicting JNDI and direct configuration
db.default {
  driver = "org.postgresql.Driver"
  url = "jdbc:postgresql://localhost/myapp" 
  jndiName = "java:comp/env/jdbc/DB"
  # Warning: Both direct config and JNDI specified, JNDI takes precedence
}

Legacy Configuration Support

Deprecated Properties

Support for legacy configuration property names:

db.default {
  # Legacy property names (deprecated but supported)
  user = "dbuser"     # Use 'username' instead  
  pass = "dbpass"     # Use 'password' instead
  
  # Current property names (preferred)
  username = "dbuser" # Overrides 'user' if both specified
  password = "dbpass" # Overrides 'pass' if both specified
}

Migration Guide

# Old format (still supported)
db.default.driver = "org.postgresql.Driver"
db.default.url = "jdbc:postgresql://localhost/myapp"
db.default.user = "dbuser"
db.default.pass = "dbpass"

# New format (recommended)
db.default {
  driver = "org.postgresql.Driver"
  url = "jdbc:postgresql://localhost/myapp"
  username = "dbuser"
  password = "dbpass"
}

Configuration Best Practices

Security

  • Never commit passwords to version control
  • Use environment variables for sensitive data
  • Consider using secret management systems
  • Encrypt configuration files in production
# Good: Use environment variables
db.default {
  username = ${DB_USERNAME}
  password = ${DB_PASSWORD}
}

# Bad: Hardcoded credentials
db.default {
  username = "hardcoded_user"
  password = "hardcoded_pass"
}

Performance

db.default {
  # Size pool appropriately for workload
  hikaricp {
    minimumIdle = 5
    maximumPoolSize = 20  # Formula: (core_count * 2) + disk_count
    
    # Configure timeouts appropriately
    connectionTimeout = 30 seconds
    idleTimeout = 10 minutes
    maxLifetime = 30 minutes
  }
}

Monitoring

db.default {
  hikaricp {
    # Enable monitoring in production
    registerMbeans = true
    leakDetectionThreshold = 60 seconds
  }
  
  # Enable SQL logging in development only
  logSql = ${?ENABLE_SQL_LOGGING}
}

Install with Tessl CLI

npx tessl i tessl/maven-com-typesafe-play--play-jdbc-2-11

docs

connection-pooling.md

database-configuration.md

database-management.md

database-operations.md

dependency-injection.md

index.md

tile.json