加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用Slick执行并发查询时,postgresql – NullPointerException异

发布时间:2020-12-13 16:28:23 所属栏目:百科 来源:网络整理
导读:我正在使用Postgres 9.3和Slick 3.1.1进行Scala应用程序.当多个查询同时执行时,我在光滑的驱动程序上得到空指针异常. 这是我的简化代码.我正在创建多个演员,它们将从数据库中调用相同的方法进行查询. package com.app.repoimport java.sql.Timestampimport a
我正在使用Postgres 9.3和Slick 3.1.1进行Scala应用程序.当多个查询同时执行时,我在光滑的驱动程序上得到空指针异常.

这是我的简化代码.我正在创建多个演员,它们将从数据库中调用相同的方法进行查询.

package com.app.repo

import java.sql.Timestamp

import akka.actor.{Actor,ActorSystem,Props}
import slick.driver.PostgresDriver
import slick.driver.PostgresDriver.api._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.FiniteDuration
import scala.util.{Failure,Success}

case class SampleData(id: Long,name: String,createDate: java.sql.Timestamp)

object Tables extends {
  val profile = PostgresDriver
} with Tables

trait Tables {
  val profile: PostgresDriver

  import profile.api._

  class SampleDataTable(_tableTag: Tag) extends Table[SampleData](_tableTag,Some("processing"),"SampleData") {
    def * = (id,name,createDate) <>(SampleData.tupled,SampleData.unapply)

    def ? = (Rep.Some(id),Rep.Some(name),Rep.Some(createDate)).shaped.<>({ r => import r._; _1.map(_ => SampleData.tupled((_1.get,_2.get,_3.get))) },(_: Any) => throw new Exception("Inserting into ? projection not supported."))

    val id: Rep[Long] = column[Long]("SampleId",O.AutoInc,O.PrimaryKey)
    val name: Rep[String] = column[String]("Name")
    val createDate: Rep[java.sql.Timestamp] = column[java.sql.Timestamp]("CreateDate")
  }

  lazy val sampleDataTable = new TableQuery(tag => new SampleDataTable(tag))
}

class SampleQueryingActor(delay: FiniteDuration,duration: FiniteDuration) extends Actor {

  import scala.concurrent.duration._

  override def preStart() = {
    context.system.scheduler.schedule(0.second,duration,self,"tick")
  }

  override def receive: Receive = {
    case "tick" => {
      println("tick received.. ")
      //val range = 1 until 1000
      RepositoryImpl.reader.onComplete({
        case Success(r)  => println(s"got sum as ${r.getOrElse(0)}")
        case Failure(ex) => ex.printStackTrace()
      })

    }
  }
}

object DriverHelper {
  val user = "postgres"
  val url = "jdbc:postgresql://192.168.1.50:5432/MyDatabase"
  val password = "password"
  val jdbcDriver = "org.postgresql.Driver"
  val db: PostgresDriver.backend.DatabaseDef = Database.forURL(url,user = user,password = password,driver = jdbcDriver)
}

object RepositoryImpl {
  val db: PostgresDriver.backend.DatabaseDef = DriverHelper.db

  val now = new Timestamp(System.currentTimeMillis())

  def reader = {
    db.run(Tables.sampleDataTable.filter(_.createDate > now).map(_.id).sum.result)
  }

  def insertBatchRecords(list: List[SampleData]) = {
    db.run(Tables.sampleDataTable ++= list)
  }

}

object PGConnectionTester extends App {

  import scala.concurrent.duration._

  val sys = ActorSystem("sys")
  sys.actorOf(Props(classOf[SampleQueryingActor],1.seconds,10.seconds))
  sys.actorOf(Props(classOf[SampleQueryingActor],10.seconds))
}

当我执行上面的代码,我得到如下错误:

java.lang.NullPointerException
    at slick.jdbc.DriverDataSource.getConnection(DriverDataSource.scala:98)
    at slick.jdbc.DataSourceJdbcDataSource.createConnection(JdbcDataSource.scala:64)
    at slick.jdbc.JdbcBackend$BaseSession.conn$lzycompute(JdbcBackend.scala:415)
    at slick.jdbc.JdbcBackend$BaseSession.conn(JdbcBackend.scala:414)
    at slick.jdbc.JdbcBackend$SessionDef$class.prepareStatement(JdbcBackend.scala:297)
    at slick.jdbc.JdbcBackend$BaseSession.prepareStatement(JdbcBackend.scala:407)
    at slick.jdbc.StatementInvoker.results(StatementInvoker.scala:33)
    at slick.jdbc.StatementInvoker.iteratorTo(StatementInvoker.scala:22)
    at slick.jdbc.Invoker$class.first(Invoker.scala:31)
    at slick.jdbc.StatementInvoker.first(StatementInvoker.scala:16)
    at slick.driver.JdbcActionComponent$QueryActionExtensionMethodsImpl$$anon$3.run(JdbcActionComponent.scala:228)
    at slick.driver.JdbcActionComponent$SimpleJdbcDriverAction.run(JdbcActionComponent.scala:32)
    at slick.driver.JdbcActionComponent$SimpleJdbcDriverAction.run(JdbcActionComponent.scala:29)
    at slick.backend.DatabaseComponent$DatabaseDef$$anon$2.liftedTree1$1(DatabaseComponent.scala:237)
    at slick.backend.DatabaseComponent$DatabaseDef$$anon$2.run(DatabaseComponent.scala:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

演员将每10秒调用相同的方法.但是,我第一次收到这个错误.之后,查询正确执行.我不明白为什么会发生这种情况.在这个示例中,只有一些简单的读操作.但是在我的实际情况下,由于查询失败,有些数据在没有正确处理的情况下会丢失.
这个错误与连接池有关吗?

我想你已经发现了 this的问题.尝试使用lazy val来分析db,这样它只能初始化一次:
object DriverHelper {
  val user = "postgres"
  val url = "jdbc:postgresql://192.168.1.50:5432/MyDatabase"
  val password = "password"
  val jdbcDriver = "org.postgresql.Driver"
  lazy val db: PostgresDriver.backend.DatabaseDef = Database.forURL(url,driver = jdbcDriver)
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读