我正在使用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,这样它只能初始化一次:
原文链接:https://www.f2er.com/postgresql/192689.htmlobject 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) }