我知道這是很經常有人問,但我不能找到一個可行的解決方案:抽象的DAO模式和Spring的「代理不能轉換爲...」的問題!
這是我AbstractDao的:
public interface AbstractDao<T>
{
public T get(Serializable id);
//other CRUD operations
}
這是我的JPA的實現:
public abstract class AbstractDaoJpaImpl<T> implements AbstractDao<T> , Serializable
{
protected EntityManager em;
protected Class<T> clazz;
@SuppressWarnings("unchecked")
public AbstractDaoJpaImpl()
{
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
this.clazz = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
}
public abstract void setEntityManager(EntityManager em);
//implementations skipped
}
這是一個實體的dao:
public interface PersonDao extends AbstractDao<Person>
{
//empty
}
這裏是它的實現:
整個體系結構是簡單的:
接口AbstractDao的定義簡單CRUD方法。
接口PersonDao擴展了AbstractDAO,沒有任何插件方法。
類AbstractDaoJpaImpl定義JPA的實現AbstractDao的
的類PersonDaoImpl延伸AbstractDaoJpaImpl並實現PersonDao的和OtherInterface,增加aditionalMethods() ...
IF,PersonDaoImpl只實現PersonDao的,沒有實現OtherInterface.additionalMethods(),一切工作正常。
我可以在Spring的XML文件中使用
<tx:annotation-driven transaction-manager="transactionManager" />
。
BUT,PersonDaoImpl實現OtherInterface(S),當測試/運行,我必須從PersonDao的鑄DAO來PersonDaoImpl或OtherInterfaces,如:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:app.xml"})
@TransactionConfiguration(transactionManager="transactionManager" , defaultRollback=false)
public class PersonDaoTest
{
@Inject
PersonDao dao;
@Test
public void testAdditionalMethod()
{
PersonDaoImpl impl = (PersonDaoImpl) dao;
System.out.println(impl.additionalMethod(...));
}
}
時發生(PersonDaoImpl) dao
的問題,這拋出「代理不能轉換到PersonDaoImpl」例外:
java.lang.ClassCastException: $Proxy36 cannot be cast to foobar.PersonDaoImpl
at foobar.PersonDaoTest.testAdditionalMethod(PersonDaoTest.java:36)
googleing時,這是經常有人問,大家都建議增加proxy-target-class="true"
到<tx:annotation-driven>
:
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
這將使使用CGLIB代替JDK的動態代理。在AbstractDaoJpaImpl的構造
Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
:
但初始化春天時,它拋出另一個異常
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
每一個問題到此爲止,我現在找不到任何工作解決方案。
任何人都可以給我一個工作解決方案嗎? 非常感謝!
環境:彈簧3.0.4,JavaEE的-API 6.0,javax.inject,CGLIB-2.2,休眠,JPA-2.0-API-1.0.0,
謝謝,我應該@Inject OtherInterface otherInterfaceImpl;並針對otherInterfaceImpl進行測試。有用 ! – smallufo 2010-10-04 22:49:12