Slick 3 insert not inserted but no error

I am trying to find Slick by doing a small test. I am trying to do an insert. The test passes, no errors, but when I check the db, no record was inserted.

What am I doing wrong?

Here's my test code:

Note. I turned off the first "flatMap" because when I wanted to test the second insert method and that code didn't execute when the first flatmap function was turned on.

Both insert methods do not insert a new record. The first query for all items works. The "Test id: xx" lines are printed to the console.

object TestSlick extends App {

  import slick.driver.PostgresDriver.api._
  import concurrent.ExecutionContext.Implicits.global
  import concurrent.duration._

  val config = ConfigFactory.load()
  val username = config.getString("app.database.jdbc.username")
  val password = config.getString("app.database.jdbc.password")
  val url: String = config.getString("app.database.jdbc.url")

  val db = Database.forURL(url, username, password)

  try {
    import Tables._

    val res = db.run(headlines.result).map(_.foreach {
      case HeadLineRow(id, _, _, _, _, companyId, text, from, days, end, user) =>
        println(s"Test id:$id")
    }).flatMap { _ =>
//      println("Inserting....")
//      val ts = Timestamp.valueOf(LocalDateTime.now())
//      val insertAction: DBIO[Option[Int]] = (headlines returning headlines.map(_.id)) +=
//        HeadLineRow(None, 100, 100, "tekst", ts, 5, ts, None, None, None, None)
//
//      db.run(insertAction.transactionally.map(
//        newId => println(s"New id: $newId"))
//      )
//    }.flatMap { _ =>
      println("Inserting....(2)")
      val ts = Timestamp.valueOf(LocalDateTime.now())
      val insertAction = headlines.map(p => p) += HeadLineRow(None, 1921, 65, "tekst2", ts, 5, ts, None, None, None, None)

      db.run(insertAction.transactionally.map(
        r => println(s"Insert result: ${r}"))
      )
    }

    Await.ready(res, 30 seconds);

  } finally db.close()
}

      

And my table (generated using the Slick generator and then the bit adjusted (auto-inc id, swaps some properties around))

package com.wanneerwerkik.db.slick

// AUTO-GENERATED Slick data model
/** Stand-alone Slick data model for immediate use */
object Tables extends {
  val profile = slick.driver.PostgresDriver
} with Tables

/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */
trait Tables {
  val profile: slick.driver.JdbcProfile
  import profile.api._
  import slick.model.ForeignKeyAction
  import slick.collection.heterogeneous._
  import slick.collection.heterogeneous.syntax._
  // NOTE: GetResult mappers for plain SQL are only generated for tables where Slick knows how to map the types of all columns.
  import slick.jdbc.{GetResult => GR}

  /** DDL for all tables. Call .create to execute. */
  lazy val schema = Array(headlines.schema).reduceLeft(_ ++ _)
  @deprecated("Use .schema instead of .ddl", "3.0")
  def ddl = schema

  /**
   * Entity class storing rows of table 'head_line_bar'
   *  @param id Database column id SqlType(int4), PrimaryKey
   *  @param createdBy Database column created_by SqlType(int4), Default(None)
   *  @param createdOn Database column created_on SqlType(timestamp), Default(None)
   *  @param updatedBy Database column updated_by SqlType(int4), Default(None)
   *  @param updatedOn Database column updated_on SqlType(timestamp), Default(None)
   *  @param companyId Database column company_id SqlType(int4), Default(None)
   *  @param contentType Database column content_type SqlType(varchar), Length(255,true), Default(None)
   *  @param fromDate Database column from_date SqlType(timestamp), Default(None)
   *  @param numberofdays Database column numberofdays SqlType(int4), Default(None)
   *  @param uptoEndDate Database column upto_end_date SqlType(timestamp), Default(None)
   *  @param userId Database column user_id SqlType(int4), Default(None)
   */
  case class HeadLineRow(
      id: Option[Int],
      userId: Int,
      companyId: Int,
      contentType: String,
      fromDate: java.sql.Timestamp,
      numberofdays: Int,
      uptoEndDate: java.sql.Timestamp,
      createdBy: Option[Int] = None,
      createdOn: Option[java.sql.Timestamp] = None,
      updatedBy: Option[Int] = None,
      updatedOn: Option[java.sql.Timestamp] = None
  )

  /** GetResult implicit for fetching HeadLineBarRow objects using plain SQL queries */
  implicit def GetResultHeadLineRow(implicit e0: GR[Int], e1: GR[Option[Int]], e2: GR[Option[java.sql.Timestamp]], e3: GR[Option[String]]): GR[HeadLineRow] = GR{
    prs => import prs._
    HeadLineRow.tupled((<<?[Int], <<[Int], <<[Int], <<[String], <<[java.sql.Timestamp], <<[Int], <<[java.sql.Timestamp], <<?[Int], <<?[java.sql.Timestamp], <<?[Int], <<?[java.sql.Timestamp]))
  }
  /**
   * Table description of table head_line_bar.
   * Objects of this class serve as prototypes for rows in queries.
   */
  class Headlines(_tableTag: Tag) extends Table[HeadLineRow](_tableTag, "head_line_bar") {
    def * = (id, userId, companyId, contentType, fromDate, numberofdays, uptoEndDate, createdBy, createdOn, updatedBy, updatedOn) <> (HeadLineRow.tupled, HeadLineRow.unapply)
    /** Maps whole row to an option. Useful for outer joins. */
    def ? = (Rep.Some(id), userId, companyId, contentType, fromDate, numberofdays, uptoEndDate, createdBy, createdOn, updatedBy, updatedOn).shaped.<>({r=>import r._; _1.map(_=> HeadLineRow.tupled((_1.get, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11)))}, (_:Any) =>  throw new Exception("Inserting into ? projection not supported."))

    /** Database column id SqlType(int4), PrimaryKey */
    val id: Rep[Option[Int]] = column[Option[Int]]("id", O.PrimaryKey, O.AutoInc)
    /** Database column user_id SqlType(int4), Default(None) */
    val userId: Rep[Int] = column[Int]("user_id")
    /** Database column company_id SqlType(int4), Default(None) */
    val companyId: Rep[Int] = column[Int]("company_id")
    /** Database column content_type SqlType(varchar), Length(255,true), Default(None) */
    val contentType: Rep[String] = column[String]("content_type", O.Length(255,varying=true))
    /** Database column from_date SqlType(timestamp), Default(None) */
    val fromDate: Rep[java.sql.Timestamp] = column[java.sql.Timestamp]("from_date")
    /** Database column numberofdays SqlType(int4), Default(None) */
    val numberofdays: Rep[Int] = column[Int]("numberofdays")
    /** Database column upto_end_date SqlType(timestamp), Default(None) */
    val uptoEndDate: Rep[java.sql.Timestamp] = column[java.sql.Timestamp]("upto_end_date")
    /** Database column created_by SqlType(int4), Default(None) */
    val createdBy: Rep[Option[Int]] = column[Option[Int]]("created_by", O.Default(None))
    /** Database column created_on SqlType(timestamp), Default(None) */
    val createdOn: Rep[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("created_on", O.Default(None))
    /** Database column updated_by SqlType(int4), Default(None) */
    val updatedBy: Rep[Option[Int]] = column[Option[Int]]("updated_by", O.Default(None))
    /** Database column updated_on SqlType(timestamp), Default(None) */
    val updatedOn: Rep[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("updated_on", O.Default(None))
  }
  /** Collection-like TableQuery object for table HeadLineBar */
  lazy val headlines = new TableQuery(tag => new Headlines(tag))

}

      

The log output is too big to be inserted here, so I put it in this method .

As I said, I added a readLine to wait for the result, but it was already outputting the same stuff. I also added a completion handler to the future to print it "Success" or "Failure". It doesn't seem to work with the RejectedExecutionException. Why?

Failure: java.util.concurrent.RejectedExecutionException: Task slick.backend.DatabaseComponent$DatabaseDef$$anon$2@2e4db0df rejected from java.util.concurrent.ThreadPoolExecutor@43760a50[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]

      

+3


source to share


1 answer


This is just a guess, but perhaps your test environment is somehow confused about flatMap

spawning a new task internally, requiring again the execution context (see, for example, this thread is around Scala 2.10, but I think it is not changed). This way, resources are freed before your insert is done.

Have you tried putting println in a finally block to see if it's called before or after the message accompanying the insert?



Have you tried running both futures in sync using wait? You probably won't get this problem in this case.

You might consider testing with full asynchronous support, see this link for example .

0


source







All Articles