मैं जानता हूँ कि यह बहुत बार पूछा जाता है, लेकिन मैं एक काम समाधान नहीं मिल सकता है:सार डीएओ पैटर्न और वसंत की "प्रॉक्सी को नहीं डाला जा सकता ..." समस्या!
यह मेरा AbstractDAO है:
public interface AbstractDao<T>
{
public T get(Serializable id);
//other CRUD operations
}
और ये मेरे जेपीए का क्रियान्वयन है:
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
}
और यह एक इकाई का दाओ है:
public interface PersonDao extends AbstractDao<Person>
{
//empty
}
यहां
@Repository
public class PersonDaoImpl extends AbstractDaoJpaImpl<Person> implements PersonDao , OtherInterface
{
@PersistenceContext(unitName="company")
@Override
public void setEntityManager(EntityManager em)
{
this.em = em;
}
@Override // implements OtherInterface.additionalMethods()
public additionalMethods()
{
// implements...
}
}
पूरे वास्तुकला सरल है::
इंटरफ़ेस AbstractDao को परिभाषित करता है सरल CRUD तरीकों इसके कार्यान्वयन है।
इंटरफ़ेस पर्सनडाओ किसी भी एडन विधियों के बिना सारडाडो को बढ़ाता है।
वर्ग AbstractDaoJpaImpl) AbstractDao
की जेपीए के कार्यान्वयनवर्ग PersonDaoImpl AbstractDaoJpaImpl प्रदान करता है और PersonDao और OtherInterface लागू करता है, जो aditionalMethods कहते हैं ( ...
यदि परिभाषित करता है, PersonDaoImpl केवल लागू करता PersonDao, अन्य इंटरफेस लागू करने के बिना .additionalMethods(), सबकुछ ठीक काम करता है।
मैं अपने वसंत के एक्सएमएल फ़ाइल में
<tx:annotation-driven transaction-manager="transactionManager" />
उपयोग कर सकते हैं।
लेकिन, PersonDaoImpl लागू करता OtherInterface (s), जब परीक्षण/चल रहा है, मैं डीएओ, जैसे PersonDaoImpl या OtherInterfaces को PersonDao से कास्ट करने के लिए है :
@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 transaction-manager="transactionManager" proxy-target-class="true" />
यह जेडीके की गतिशील प्रॉक्सी के बजाय CGLIB का उपयोग करेगा।
लेकिन यह एक और अपवाद फेंकता है जब वसंत आरंभ: 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, हाइबरनेट-जेपीए-2.0-api-1.0.0,
धन्यवाद, मुझे अन्य इंटरफेस अन्य इंटरफेसइंपल इंजेक्ट करना चाहिए; और अन्यInterfaceImpl के खिलाफ परीक्षण। यह काम करता हैं ! – smallufo