I'm currently working on a pet store application using ZIO and Quill. As part of my learning process, I've set up a local H2 database and configured it to store pet information. However, I'm encountering an issue when trying to fetch pets from the database using ZIO Quill.
I've defined the Pet case class and provided the implicit SchemaMeta inside its companion object. However, when I try to fetch pets, I get the following error:
Can't find an implicit
SchemaMeta
for typemodels.Pet
.
I'm not sure what's causing this issue. I've checked my imports and dependencies, and they seem to be correct. Additionally, I've ensured that the table name and column names in my database match those specified in my Quill schema definitions.
Could someone please help me understand why I'm encountering this error and how I can resolve it?
package models
import config.QuillContext.{querySchema, quote}
import io.getquill.{EntityQuery, Quoted}
import zio.json.{DeriveJsonCodec, JsonCodec}
import zio.schema.{DeriveSchema, Schema}
import java.util.UUID
final case class Pet(
petId:UUID,
name: String,
species:String,
ownerId:UUID
)
object Pet {
implicit val petSchemaMeta: Quoted[EntityQuery[Pet]] = quote {
querySchema[Pet](
"PETS",
_.petId -> "PET_ID",
_.name -> "NAME",
_.species -> "SPECIES",
_.ownerId -> "OWNER_ID"
)
}
implicit val codec: JsonCodec[Pet] = DeriveJsonCodec.gen[Pet]
implicit val petSchema: Schema[Pet] = DeriveSchema.gen[Pet]
}
Quill Context
package config
import com.zaxxer.hikari.{HikariConfig, HikariDataSource}
import io.getquill.{H2ZioJdbcContext, SnakeCase, UpperCase}
import models.Pet
import zio.ZLayer
import javax.sql.DataSource
object QuillContext extends H2ZioJdbcContext(UpperCase){
val dburl = "jdbc:h2:./test"
val userName = "sa"
val password = "password"
val h2dbConfig = new HikariConfig()
h2dbConfig.setJdbcUrl(dburl)
h2dbConfig.setUsername(userName)
h2dbConfig.setPassword(password)
val dataSource = new HikariDataSource(h2dbConfig)
val dataSourceLayer:ZLayer[Any,Throwable,DataSource] = ZLayer.succeed(dataSource)
//added Schema Meta
implicit val petSchemaMeta: SchemaMeta[Pet] = schemaMeta[Pet]("pets")
}
build.sbt
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.13.13"
lazy val root = (project in file("."))
.settings(
name := "zio-pets-learn"
)
libraryDependencies ++= Seq(
"dev.zio" %% "zio" % "2.1-RC1",
"io.getquill" %% "quill-zio" % "4.8.0",
"io.getquill" %% "quill-jdbc-zio" % "4.8.1",
"com.h2database" % "h2" % "2.2.224",
"dev.zio" %% "zio-schema" % "0.4.15",
"dev.zio" %% "zio-schema-derivation" % "0.4.15",
"org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided"
)
Thank you!
If implicits of type SomeTypeclass[SomeDatatype]
should be found without import, then one should normally put them into companion object of SomeTypeclass
or SomeDatatype
Where does Scala look for implicits?
Encoding and Decoding for Student Case Class with Animal Trait
Now
implicit val petSchemaMeta: SchemaMeta[Pet] = schemaMeta[Pet]("pets")
is defined in object QuillContext
, not in companion object of SchemaMeta
or Pet
, so it's out of implicit scope and should be imported explicitly.
If you replace
import config.QuillContext.{run, query}
with
import config.QuillContext.{run, query, petSchemaMeta}
then compile error
[error] zio-pets-learn/src/main/scala/PetService.scala:22:26: Can't find an implicit `SchemaMeta` for type `models.Pet`
[error] run(query[Pet]).provideEnvironment(ZEnvironment(dataSource))
[error] ^
changes to
// (*)
[error] zio-pets-learn/src/main/scala/PetService.scala:22:26: type mismatch;
[error] found : io.getquill.Quoted[io.getquill.EntityQuery[models.Pet]]
[error] required: io.getquill.EntityQuery[models.Pet]
[error] run(query[Pet]).provideEnvironment(ZEnvironment(dataSource))
[error] ^
The thing is that implicit SchemaMeta
are expected to be imported with _
(probably because of some macro magic some implicit conversion not found)def run[T](quoted: Quoted[Query[T]]): Result[RunQueryResult[T]] = macro QueryMacro.runQuery[T]
or
https://github.com/zio/zio-quill/issues/1860
So replace the import with
import config.QuillContext._
Then the code compiles
https://github.com/siva3060/zio-pets-learn/pull/1
https://github.com/DmytroMitin/zio-pets-learn/actions/runs/8128575397/job/22214609741
Also the following import seems to be working in your case
import config.QuillContext.{run, query, petSchemaMeta, quote, unquote}
Implicit conversions quote
/unquote
are necessary for conversions between T
and Quoted[T]
, e.g. EntityQuery[Pet]
and Quoted[EntityQuery[Pet]]
in (*).
How to debug implicits (at compile time): In scala 2 or 3, is it possible to debug implicit resolution process in runtime?