开发者

$Proxy25 cannot be cast to my class spring framework

开发者 https://www.devze.com 2023-02-26 21:28 出处:网络
I am getting this exception while running a Test (I am trying to configure aop in spring): java.lang.ClassCastException: $Proxy25 cannot be cast to path.UserDao

I am getting this exception while running a Test (I am trying to configure aop in spring):

java.lang.ClassCastException: $Proxy25 cannot be cast to path.UserDao
    at com.playence.app.daoTests.TestCreateOntologyDB.testGenerateGlobalAnnotation(TestCreateOntologyDB.java:49)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
    at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
    at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)   

UserDao.java

public class UserDao extends AbstractHibernateDAOSupport {

    public UserDao() {
        super();
    }

    /**
     * Insert a new User into the database.
     * 
     * @param user
     */
    public void store(User user) throws DataAccessLayerException {
        super.save(user);
    }

    /**
     * Delete a User from the database.
     * 
     * @param user
     */
    public void delete(User user) throws DataAccessLayerException {
        super.delete(user);
    }

    /**
     * Updates the state of a detached开发者_运维知识库 User.
     * 
     * @param user
     */
    public void update(User user) throws DataAccessLayerException {
        super.update(user);
    }

    public User findByID(String id) throws DataAccessLayerException {
        return (User) this.find(User.class, id);

    }

    /**
     * Finds all Users in the database.
     * 
     * @return
     */
    public List findAll() throws DataAccessLayerException {
        return super.findAll(User.class);
    }

Spring configuration files: applicationContext-dao.xml

<bean id="userDao" class="path.UserDao">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>

TestCreateOntologyDB.java

....  
ApplicationContext ctx ;

    public TestCreateOntologyDB() {
        ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
    }

    @Test
    public void testGenerateGlobalAnnotation(){
        UserDao userDao = (UserDao)ctx.getBean("userDao");

...

And I haven't set up any UserDao additional propperty in any other configuration file. What could be the error?? Any help would be appreciated. Thanks in advance


Finally I found the sollution:

  1. Create interface for the classes which will use aop
  2. Edit the path to the correct one in spring configuration file:

  3. Add this line in the same configuration file. Be aware that in my case it will influence in all the beans, but it can be included for just one bean.

The whole topic is here http://forum.springsource.org/showthread.php?p=357883


If you are using Java based configuration, you need to add the @EnableAspectJAutoProxy annotation on you Configuration class and set proxyTargetClass to true.

@Configuration
@ImportResource("classpath:beanConfiguration.xml")
@ComponentScan(basePackages="com.bpjoshi.foo")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class NotificationConfig {

}

For detailed explanation visit this official spring documentation

If you are using xml configuration for spring add the code below to your bean-config.xml

<aop:aspectj-autoproxy proxy-target-class="true"/>


It looks like, you are using Spring AOP Proxy and try to cast something that should be an UserDao to UserDao, but it is not the UserDao because of the proxy stuff.


For more details you should post the code that causes the error:

com.playence.app.daoTests.TestCreateOntologyDB.testGenerateGlobalAnnotation(TestCreateOntologyDB.java:49)

Strange, did you tryed AbstractApplicationContext.getBean(String name, Class<T> requiredType) instead of explicit cast?


In my humble opinion: I strongly recommend to use AspectJ instead


You need to enable target-class-proxying for that to work. Set the property proxyTargetClass to true to make it work or create a PersonDao interface, rename your dao to PersonDaoImpl and let your classes work with the interface instead of the class.


I faced a similar issue once.

I was using the getBean() method of my ApplicationContext to try to get a particular repository class, but it would throw a ClassCastException similar to the OP.

The underlying reason was that one of my methods in the repository class I was trying to get was annotated with the @Cacheable, which meant that Spring was going to create a proxy for that class.

I got around this by moving the @Cacheable annotation to a method inside a service class as opposed to a repository class.

0

精彩评论

暂无评论...
验证码 换一张
取 消