Nitin Pandey
Nitin Pandey

Reputation: 719

avro4s : could not find implicit value for parameter schemaFor: com.sksamuel.avro4s.SchemaFor[T]

My requirement takes a class and should return me an avro-schema using avro4s. Below is the code, I'm trying:

The idea is to achieve something like this


import scala.reflect.ClassTag
import com.sksamuel.avro4s.AvroSchema

case class Ingredient(name: String, sugar: Double, fat: Double)

case class Pizza(
    name: String,
    ingredients: Seq[Ingredient],
    vegetarian: Boolean,
    vegan: Boolean,
    calories: Int
)

class AvroUtil[T: ClassTag](implicit m: Manifest[T]) {

  def caseClassToAvroSchema() = {
    val schema = AvroSchema[T]
    schema
  }

}

new AvroUtil[Pizza].caseClassToAvroSchema()

How can I fix this?

Error - could not find implicit value for parameter schemaFor: com.sksamuel.avro4s.SchemaFor[T]

Scala Version - 2.12.8

Avro4s - "com.sksamuel.avro4s" %% "avro4s-core" % "3.1.1"

Upvotes: 0

Views: 1533

Answers (1)

ExploreTech
ExploreTech

Reputation: 1

I see that the context bound '[T: ClassTag]' info in AvroUtil is causing the error.

Referring the 'apply[T](implicit schemaFor: SchemaFor[T])' method of standalone object 'AvroSchema' (above invoked via 'AvroSchema[T]'): If the method is not supplied with parameter value and the compiler finds no implicit object in scope then by default there will be an implicit 'SchemaFor[T]' instance that would be created via the trait 'MagnoliaDerivedSchemaFors':

implicit def gen[T]: SchemaFor[T] = macro Magnolia.gen[T]

The context bound info is refraining from constructing this default object and as a result you are getting the error. Seems like it is nice to use existing 'AvroSchema' standalone object apply method rather than having a new class. The other way is to convert 'AvroUtil' into a standalone object (something like below code that is quite similar to 'AvroSchema') and use the apply method:

import com.sksamuel.avro4s.{AvroSchema, SchemaFor}
import org.apache.avro.Schema    

object AvroUtil {

      def apply[T](implicit schemaFor: SchemaFor[T]): Schema =
        AvroSchema[T](schemaFor)
    }

Upvotes: 0

Related Questions