gpt4 book ai didi

java - 对 hibernate 应用程序使用@Transactional 注释导致错误

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:46:01 25 4
gpt4 key购买 nike

今天早上我正在尝试将 spring 与 hibernate 集成。我想使用 spring 事务管理器。但是出现以下错误。该错误与@Trasactional 注释有关。如果我删除注释,我就可以从 spring 容器中获取 bean。

Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy19 cannot be cast to com.hibernate.dao.EvntDAOImpl
at com.hibernate.action.HibernateAction.main(HibernateAction.java:17)

我粘贴在我的源代码下面。

POM.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hibernate-tutorials</groupId>
<artifactId>hibernate-tutorials</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<spring-framework.version>4.0.3.RELEASE</spring-framework.version>
<hibernate.version>4.3.5.Final</hibernate.version>
<slf4j.version>1.7.5</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>

<!-- Spring ORM support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring-framework.version}</version>
</dependency>

<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.2.0</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
</dependencies>

hibernate 配置

<?xml version="1.0" encoding="UTF-8"?>

http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.hibernate.model.Evnt</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>

<bean id="transactionManager"
class="org.springframework.orm.hibernatey.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

EvntDAOImpl.java

package com.hibernate.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.hibernate.model.Evnt;

@Repository(value="evntDAO")
@Transactional
public class EvntDAOImpl implements EvntDAO {

@Autowired
private SessionFactory sessionFactory;

@Override
public void storeEvnt(Evnt evnt) {

sessionFactory.getCurrentSession().save(evnt);

}

HibernateAction.java

package com.hibernate.action;

import java.util.Date;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hibernate.dao.EvntDAO;
import com.hibernate.dao.EvntDAOImpl;
import com.hibernate.model.Evnt;

public class HibernateAction {

public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

EvntDAOImpl evntDAO = (EvntDAOImpl) context.getBean("evntDAO");
Evnt evnt = new Evnt();
evnt.setTitle("first Event");
evnt.setDate(new Date());
evntDAO.storeEvnt(evnt);

}
}

提前致谢...

最佳答案

问题出在你注入(inject) EventDaoImpl 的地方。

只是替换

@Autowired EventDaoImpl eventDaoImpl

@Autowired EventDao 事件道

任何你需要 Spring 来 Autowiring dao 的地方。

或者如果您从 applicationContext 使用获取 bean:

EvntDAO evntDAO = (EvntDAO) context.getBean("evntDAO");

问题是由于在dao的实现代码上使用了@Transactional注解,意味着Spring会创建一个JDK dynamic proxy。对于它,不能将其强制转换为实现类。 Here是 Spring 的 AOP 功能的完整文档(其中完整解释了 JDK 动态代理和 CGLib 类代理的创建)。

这本质上意味着因为 @Transactional,当您调用 context.getBean("evntDAO") 时,您不会取回您的 EventDaoImpl (正如人们所期望的那样),但您实际上得到了一个类为 java.lang.reflect.Proxy 的对象,它是由 Spring 创建的。该代理对象实现了 EventDao(因此可以转换为它)但它的签名与 EventDaoImpl 无关(因此 ClassCastException 因为它不扩展 EventDaoImpl)。当在代理上调用方法时,在调用实际委托(delegate)给 EventDaoImpl 之前和/或之后会发生各种事情(在实际调用 EventDaoImpl 之前/之后发生的事情通过 InvocationHandler 的实现由 Spring 控制)。

关于java - 对 hibernate 应用程序使用@Transactional 注释导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26073318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com