Reputation: 901
I'm new to Scala, so its probable that this is an incredibly obvious mistake. However, I'm trying to cast a List[Object] into List[A], where A is a parameter in the class.
class AbstractHibernateDAO[A<:Serializable]{
def findAll: List[A] = {
val objList = currentSession.createQuery("from " + clazz.getName()).list()
objList.map{_.asInstanceOf[A]}
}
}
Eclipse is puking up:
type mismatch; found : ?0(in method findAll) => A where type ?0(in method findAll) required: (some other)?0(in method findAll) => ? where type (some other)?0(in method findAll) AbstractHibernateDAO.scala /springHibernateNoXML/src/main/scala/my/package
I've also tried the long form
objList.map{obj => obj.asInstanceOf[A]}
and get the same result.
Can anyone give me a hand?
[EDIT - Additional information]
For those that requested, here's the full listing:
package name.me
import java.io.Serializable
import java.util.List
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.config.BeanDefinition
import org.springframework.context.annotation.Scope
import org.springframework.orm.hibernate3.HibernateTemplate
import org.springframework.stereotype.Repository
import com.google.common.base.Preconditions
import org.hibernate.SessionFactory
import org.hibernate.Session
import collection.JavaConversions._
@Repository
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
class AbstractHibernateDAO[A<:Serializable]{
val clazz: Class[A] = null
@Autowired val sessionFactory: SessionFactory = null
def currentSession: Session = {
sessionFactory getCurrentSession
}
def findOne(id: Long): A = {
Preconditions checkArgument(id != null)
currentSession.get(clazz, id).asInstanceOf[A]
}
def findAll: List[A] = {
val objList = currentSession.createQuery("from " + clazz.getName()).list()
objList.map(_.asInstanceOf[A])
//This works
//objList.asInstanceOf[List[A]]
}
def save(entity:A){
Preconditions checkNotNull entity
currentSession persist entity
}
def update(entity: A){
Preconditions checkNotNull entity
currentSession merge entity
}
def delete(entity: A){
Preconditions checkNotNull entity
currentSession delete entity
}
def deleteById(entityId: Long){
Preconditions checkNotNull entityId
val entity = findOne(entityId)
Preconditions checkNotNull entity
delete(entity)
}
}
Upvotes: 2
Views: 322
Reputation: 51109
A quick look at the Hibernate API docs shows that Query.list()
returns a java.util.List
, but you have a type annotation of List[A]
, which is by default (from the scala package object) a scala.collection.immutable.List
.
Which do you want to return?
for Java List, change your type annotation and cast the whole list:
class AbstractHibernateDAO[A<:Serializable]{
def findAll: java.util.List[A] = {
val objList = currentSession.createQuery("from " + clazz.getName()).list()
objList.asInstanceOf[java.util.List[A]]
}
}
for Scala List, use JavaConversions:
class AbstractHibernateDAO[A<:Serializable]{
def findAll: List[A] = {
val objList = currentSession.createQuery("from " + clazz.getName()).list()
import collection.JavaConversions._
objList.toList.asInstanceOf[List[A]]
}
}
Upvotes: 2
Reputation: 52701
Are you sure of the type of objList
? Is it really a scala.collection.immutable.List
of java.util.Object
? You can check this easily by adding a type to your variable declaration:
val objList: List[java.util.Object] = ...
Assuming that's correct, your code seems fine. But I can't run it without having all the other code. I can do what you are trying with a simplified example:
def convertAll[A](data: List[java.lang.Object]): List[A] =
data.map(_.asInstanceOf[A])
convertAll[java.lang.Integer](List(1,2).map(new java.lang.Integer(_)))
// List[java.lang.Integer] = List(1, 2)
However, you shouldn't need to cast each item in the List
. Try just casting the list to its new type:
objList.asInstanceOf[List[A]]
For example:
val x: List[java.lang.Object] = List(1,2).map(new java.lang.Integer(_))
x.asInstanceOf[List[java.lang.Integer]]
// List[java.lang.Integer] = List(1, 2)
Upvotes: 3