Setting Up Play Framework Evolutions with Dependency Injection and MySQL

If you wanted Play Framework, DB migrations, MySQL, and compile time dependency injection, you might have a tough time with Play's documentation. We've been there, and here's how we did it.

If you’re anything like us, you love Scala and Play Framework. You are probably a fierce advocate of compile time dependency injection (who wants to have to actually run their app to know if it’s correct?). You definitely have a database and want to use Play Framework’s evolutions for database migrations. However, if you read Play’s documentation, you’ll find that it’s a little incomplete and you need to do a little detective work through the Scaladocs to piece things together. We did that digging when we set up our MySQL databases with Play, and have compiled our findings here so you don’t have to waste time searching. This guide expects working knowledge of compile time DI in Play.

First, you’ll need to add the correct dependencies to your project definition’s settings in SBT.

import play.sbt.PlayImport._

...

.settings(
  libraryDependencies ++= Seq(
    // or whatever jdbc connector you use
    "mysql" % "mysql-connector-java" % "5.1.36",
    PlayImport.evolutions,
    PlayImport.jdbc,
    ...
  )
)

Next, you’ll want to set up the class that extends play.api.BuiltInComponentsFromContext. It will need to mix in some components that give you access to the database and the Evolutions system.

import play.api.BuiltInComponentsFromContext
import play.api.ApplicationLoader.Context
import play.api.db.{DBComponents, HikariCPComponents}
import play.api.db.evolutions.EvolutionsComponents

class AppComponents(cntx: Context)
  extends BuiltInComponentsFromContext(cntx)
  with DBComponents
  with EvolutionsComponents
  with HikariCPComponents
{
  // this will actually run the database migrations on startup
  applicationEvolutions

  // set up the model by passing in a play.api.db.Database object
  // for connections to the database
  private[this] val db = dbApi.database("default")
  private[this] val model = new AppModel(db)

  ...
}

By the way, we highly recommend using both Relate, a database query tool in Scala, and Macwire, which helps resolve dependencies in Scala.

Play’s documentation mentions EvolutionsComponents, but you’ll also need DBComponents to provide the dbApi that EvolutionsComponents needs, and mixing in HikariCPComponents will let you use Play’s default connection pooling. You’ll also have to get an instance of play.api.db.Database to pass to your models so you can get database connections.

That’s it! Now that you’ve provided a Database object to your model, you can query your databases just like the examples in Play’s documentation!

import play.api.db.Database

class AppModel(db: Database) {
  ...
  db.withConnection { connection =>
    // your query here
  }
  ...
}
Picture of Mark Siebert

Mark Siebert

Author Bio

Mark is a full-stack engineer who cut his teeth on professional software development at Lucid Software where he specialized in building scalable backend systems. He's a huge fan of open source software and is one of the primary authors of Relate (database access library) and Cumulus (AWS infrastructure management). Mark loves watching shows with his wife, studying Chinese, and hunting Minecraft chickens.

What is Blue Matador?

Blue Matador is the AI-powered DevOps monitoring platform that provides real-time, predictive alerts that help your team decrease downtime and increase customer confidence in your brand. Learn more

Our Monitoring Products

Watchdog is the free server monitor that sends you and your team proactive system vitals alerts, proactively notifying you of all the metrics you need to know to prevent downtime. Install for free


Lumberjack is the AI-powered centralized log management tool that proactively warns your DevOps team of impending server and app issues that affect uptime. Try free for 14 days