$Proxy25 无法转换为我的类 Spring 框架

发布于 2024-11-01 17:26:59 字数 3862 浏览 5 评论 0原文

我在运行测试时遇到此异常(我试图在 spring 中配置 aop):

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 配置文件: 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");

...

并且我没有在任何其他配置文件中设置任何 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

归属感 2024-11-08 17:26:59

最后我找到了解决方案:

  1. 为将使用aop的类创建接口
  2. 在spring配置文件中编辑正确路径:

  3. 在同一配置文件中添加此行。请注意,在我的情况下,它将影响所有豆子,但它可以只影响一种豆子。

整个主题在这里 http://forum.springsource.org/showthread.php?p= 357883

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

神爱温柔 2024-11-08 17:26:59

如果您使用基于 Java 的配置,则需要在 Configuration 类上添加 @EnableAspectJAutoProxy 注释并将 proxyTargetClass 设置为 true。

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

}

详细解释请访问这个官方spring 文档

如果您使用 spring 的 xml 配置,请将以下代码添加到您的 bean-config.xml 中

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

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"/>
战皆罪 2024-11-08 17:26:59

看起来,您正在使用 Spring AOP 代理,并尝试将应该是 UserDao 的东西转换为 UserDao,但由于代理的原因,它不是 UserDao。


有关更多详细信息,您应该发布代码导致错误:

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

奇怪,您是否尝试过 AbstractApplicationContext.getBean(String name, ClassrequiredType) 而不是显式强制转换?


以我的拙见:我强烈建议使用 AspectJ

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

陪你搞怪i 2024-11-08 17:26:59

您需要启用目标类代理才能正常工作。将属性 proxyTargetClass 设置为 true 以使其工作或创建 PersonDao 接口,将您的 dao 重命名为 PersonDaoImpl 并让您的类使用该接口而不是类。

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.

世界等同你 2024-11-08 17:26:59

我曾经遇到过类似的问题。

我使用 ApplicationContextgetBean() 方法尝试获取特定的存储库类,但它会抛出类似于以下内容的 ClassCastException OP。

根本原因是我试图获取的存储库类中的一个方法被 @Cacheable 注释,这意味着 Spring 将为该类创建一个代理。

我通过将 @Cacheable 注释移至服务类(而不是存储库类)内的方法来解决此问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文