Slick

2016-02-01 8 views
15

का उपयोग कर समवर्ती प्रश्नों को निष्पादित करने पर NullPointerException मैं Postgres 9.3 और Slick 3.1.1 के साथ स्कैला एप्लिकेशन पर काम कर रहा हूं। जब मैं कई प्रश्नों को एक ही समय में निष्पादित करता हूं तो मुझे स्लिम ड्राइवर पर नल पॉइंटर अपवाद मिल रहा है।Slick

यहाँ मेरी सरलीकृत कोड है। मैं कई कलाकार बना रहा हूं जो डेटाबेस से क्वेरी करने के लिए एक ही विधि को कॉल करेंगे।

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], 1.seconds, 10.seconds)) 
    sys.actorOf(Props(classOf[SampleQueryingActor], 1.seconds, 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 सेकंड। हालांकि, मैं केवल पहली बार के लिए इस त्रुटि हो रही है। उसके बाद प्रश्न सही तरीके से निष्पादित कर रहे हैं। मैं समझ नहीं पा रहा हूं कि यह क्यों हो रहा है। इस नमूना मामले में, केवल कुछ सरल पठन ऑपरेशन हैं। लेकिन मेरे वास्तविक मामले में, चूंकि क्वेरी विफल हो रही है, इसलिए कुछ डेटा सही तरीके से संसाधित किए बिना खो जा रहा है। क्या यह त्रुटि कनेक्शन पूलिंग के साथ कुछ करने के लिए है?

+2

यहाँ एक नज़र डालें: https://github.com/slick/slick/issues/1400 – Dima

+2

धन्यवाद @Dima। मैंने HikariCP पूलिंग लागू की, और यह मुद्दा अब के लिए तय किया गया प्रतीत होता है। –

+0

नहीं .. हिकारी के उपयोग के बाद भी वही त्रुटि मिल रही है। :( –

उत्तर

0

बस किसी और को इस मुद्दे का सामना करना पड़ के लिए जानकारी साझा।

स्लिम के साथ एक बग था। यह here की सूचना दी गई थी। गिट उपयोगकर्ता, Mustajavi इसे तय किया और नवीनतम Slick शाखा में विलय कर दिया गया था। 3.1.1 के नवीनतम अपडेट के साथ, मेरे लिए समस्या हल हो गई है। GitHub में

संबंधित लिंक:

https://github.com/slick/slick/pull/1401

https://github.com/slick/slick/pull/1445

+0

मुझे अभी भी 3.1.1 में त्रुटि मिल रही है –

3

मुझे लगता है कि आपको this समस्या मिली है। तो यह केवल एक बार initializes डाटाबेस के लिए आलसी वैल का उपयोग करने का प्रयास करें:

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, user = user, password = password, driver = jdbcDriver) 
} 
+0

हम्म, क्योंकि वह कई धागे से 'डीबी' तक पहुंच रहा है, डेटाबेस निर्माण शायद सिंक्रनाइज़ किया जाना चाहिए? –

+0

अच्छी तरह से, स्लिक स्वयं सिंक्रनाइज़ेशन का प्रबंधन करता है, विशेष रूप से db.run() – vitalii

+0

के निर्माण के साथ स्लिक के साथ एक बग था। इसे ठीक कर दिया गया है और दो दिन पहले 3.1.1 की कमी के लिए विलय कर दिया गया है। यहां लिंक है। Https://github.com/slick/slick/pull/1401 –

संबंधित मुद्दे