2012-04-22 64 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