2012-04-22 32 views
2

我是斯卡拉新手,所以很可能这是一个非常明显的错误。但是,我试图将List [Object]转换为List [A],其中A是类中的参数。斯卡拉地图方法不像预期的那样行事

class AbstractHibernateDAO[A<:Serializable]{ 
    def findAll: List[A] = { 
    val objList = currentSession.createQuery("from " + clazz.getName()).list() 
    objList.map{_.asInstanceOf[A]} 
    } 
} 

Eclipse是呕吐了起来:

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 

我也试着长期形成

objList.map{obj => obj.asInstanceOf[A]} 

,并得到同样的结果。

任何人都可以帮我一把吗?

[编辑 - 信息]

对于那些要求,这里的完整清单:

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) 
    } 
} 
+0

凡'clazz'定义? – 2012-04-22 17:05:31

回答

2

就让我们来看看在Hibernate API docs表明Query.list()返回java.util.List,但你有List[A]类型注释,这是默认的(从scala package object)a scala.collection.immutable.List

你想要返回哪个?

为Java列表,改变你的类型的注释和投全名单:

class AbstractHibernateDAO[A<:Serializable]{ 
    def findAll: java.util.List[A] = { 
    val objList = currentSession.createQuery("from " + clazz.getName()).list() 
    objList.asInstanceOf[java.util.List[A]] 
    } 
} 

斯卡拉列表,使用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]] 
    } 
} 
+0

我想返回一个scala.collection.immutable.List。我应该收到一个Java。来自Hibernate的util.List (至少这是我的理解)。我想动态地将其转换为scala.collection.immutable.List 。 – babbitt 2012-04-23 16:01:37

+0

@babbitt好,按照我在这个答案中的建议做。它不能用于映射和转换的原因是因为JavaConversions中的隐式转换将java.util.List转换为Buffer,而不是Scala List,由于List不是Buffer的子类,转换将失败。所以你需要那里的'toList'。 – 2012-04-23 16:16:45

+0

谢谢。今天下午我会回头看看这个项目。 – babbitt 2012-04-23 16:21:20

3

确定的objList类型的?它真的是java.util.Objectscala.collection.immutable.List?您可以通过在您的变量声明中添加一个类型来轻松检查:

val objList: List[java.util.Object] = ... 

假设这是正确的,您的代码看起来很好。但是如果没有所有其他代码,我就无法运行它。我可以做你用一个简单的例子尝试:

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) 

但是,你不应该需要在List投每个项目。尝试只是投放在列表中的新类型:

objList.asInstanceOf[List[A]] 

例如:

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) 
+0

我试着验证列表是List [java.lang.Object],并且发现它的类型是Java.util.List [?0]。我确实有导入了collection.JavaConversions._,我认为这是向scala.collection.immutable.List提供动态上传。投射整个列表工作。 – babbitt 2012-04-23 12:03:52

+0

@babbit你确定这不会在运行时产生ClassCastException吗? (因为它在REPL中尝试时会出现) – 2012-04-23 12:22:35

+0

@Luigi不,我不确定。我只有几分钟的时间来改变建议的代码,并发现它解决了日食所抱怨的错误。我还没有运行我的测试(仍然需要从Java转换我的测试套件)。 – babbitt 2012-04-23 15:58:55