Java generics

71 views
Skip to first unread message

José Guilherme Vanz

unread,
May 18, 2015, 3:58:37 PM5/18/15
to scala...@googlegroups.com
Hi, folks!

I'm newbie in Scala world and I'm developing an application using Play Framework and Cassandra. For access the Cassandra I use the Datastax Java driver.
In my application I have the following class. This class, like you can see in the snippet, is a mapped Cassandra column family.

@Table(keyspace="gathering", name="raw")
class Raw(@PartitionKey @Column(name="creation_id") creationId: Int, @ClusteringColumn @Column(name="input_id") inputId: java.util.UUID,
   
@Column(name="data") data: String)

And the following code is where I try to save some obj in the database

    def save(obj: AnyRef) = {
        mappingManager
.mapper(obj.getClass).save(obj)
   
}

And when I compile the source code I can see these errors:
[error] /path/to/file/Cassandra.scala:67: type mismatch;
[error]  found   : obj.type (with underlying type AnyRef)
[error]  required: ?0 where type ?0 <: AnyRef
[error]                 mappingManager.mapper(obj.getClass).save(obj)

Somebody can help me to solve these problem? I guess is something wrong with using Java generics within Scala

The javadoc of the MappingManager and Mapper used can be found here

Thank you

Adriaan Moors

unread,
May 18, 2015, 5:49:47 PM5/18/15
to José Guilherme Vanz, scala-user
Hi, 

This is because Scala doesn't support Java's wildcard capture, which is needed to make Java's use-site approach to variance work (where the API user needs to express variance using wildcards).
In Scala we have definition-site variance, so you don't really have to think about it, and the type checker doesn't have to jump through hoops to hide it from you.

We'd like to improve this in 2.12 because this will come up a lot when working with Java-defined functional interfaces, but not sure yet how...

That said, you can work around this as follows (still thinking about a better way):


$ sbt
> set libraryDependencies += "com.datastax.cassandra" % "cassandra-driver-core"    % "2.1.5"
> set libraryDependencies += "com.datastax.cassandra" % "cassandra-driver-mapping" % "2.1.5"
> console
scala> import com.datastax.driver.mapping._

// pretend Class is covariant in T
scala> type ClassCov[+T] = Class[T @annotation.unchecked.uncheckedVariance]
scala> def cls[T <: AnyRef](obj: T): ClassCov[T] = obj.getClass.asInstanceOf[ClassCov[T]]

scala> val mappingManager = new MappingManager(null)
mappingManager: com.datastax.driver.mapping.MappingManager = com.datastax.driver.mapping.MappingManager@31c3c8b0

scala> def save(obj: AnyRef) = mappingManager.mapper(cls(obj)).save(obj)
save: (obj: AnyRef)Unit

cheers
adriaan

José Guilherme Vanz

unread,
May 19, 2015, 7:26:28 AM5/19/15
to Adriaan Moors, scala-user
Nice. I got it. =]
Thank you for your explanation!

Reply all
Reply to author
Forward
0 new messages