2

I'm working on this project in Scala and I'm testing one of my services with a local dynamodb database. I am using the 3rd party library awscala in order to access the table. I'm having a bit of trouble with this part of the code:

 override def put(status: Status) = {
   require(null != status, "The status object cannot be null.")

   table.put(status.id, "State" -> status.state)
 }

 override def get(id: String): Option[Status] = {
   require(StringUtils.isNotBlank(id), "The id of the status cannot be empty/null.")

   val state = dynamoDB.get(table, id)
   new Status(id, state)
 }

Status is a class that I define; it has fields ID: String and state: State, where State is a case class that I defined. When I get something from the table based on the id, and try to create a new Status object, the type of the thing returned is Option[awscala.dynamodbv2.Item] but it requires type enums.State (the case class I defined).

How would I case state to be of type enums.State?

EDIT: Added the definition of state and its case objects.

sealed trait State {}
case object COMPLETED_SUCCESSFULLY extends State {}
case object FINISHED_POLLING extends State {}
case object CURRENTLY_DOWNLOADING extends State {}
case object FINISHED_DOWNLOADING extends State {}
1
  • Can you show the definition of the enum State and its members? Commented Aug 14, 2015 at 8:50

1 Answer 1

2

Looking at the source code for the library you're using, it looks like table.put won't behave as you expect when the right hand side of -> is not a string, number, or byte buffer. It will store null.

https://github.com/seratch/AWScala/blob/master/src/main/scala/awscala/dynamodbv2/AttributeValue.scala

The relevant code is:

def toJavaValue(v: Any): aws.model.AttributeValue = {
    val value = new aws.model.AttributeValue
    v match {
      case null => null
      case s: String => value.withS(s)
      case n: java.lang.Number => value.withN(n.toString)
      case b: ByteBuffer => value.withB(b)
      case xs: Seq[_] => xs.headOption match {
        case Some(s: String) => value.withSS(xs.map(_.asInstanceOf[String]).asJava)
        case Some(n: java.lang.Number) => value.withSS(xs.map(_.toString).asJava)
        case Some(s: ByteBuffer) => value.withBS(xs.map(_.asInstanceOf[ByteBuffer]).asJava)
        case Some(v) => value.withSS(xs.map(_.toString).asJava)
        case _ => null
      }
      case _ => null
    }
  }

I suggest you write some code to marshall your enums to and from strings, and store and retrieve those.

Sign up to request clarification or add additional context in comments.

1 Comment

Yep that's what we ended up doing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.