2014-09-27 5 views
2

오늘 아침에 최대 절전 모드로 봄을 통합하려고합니다. 스프링 트랜잭션 관리자를 사용하고 싶습니다. 하지만 아래 오류가 발생했습니다. 이 오류는 @Trasactional Annotation과 관련이 있습니다. 주석을 제거하면 스프링 컨테이너에서 콩을 가져올 수 있습니다.최대 절전 모드 응용 프로그램에 @Transactional 주석을 사용하여 오류가 발생했습니다.

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> 

최대 절전 모드 구성

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

http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/txhttp://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); 

    } 
} 

미리 감사드립니다 ...

답변

5

문제는 EventDaoImpl을 주사하고있는 곳입니다.

그냥 당신이 DAO를 autowire하기 위해 스프링을 필요로 어디든지

@Autowired EventDao eventDao

@Autowired EventDaoImpl eventDaoImpl

를 교체합니다.

아니면 ApplicationContext를 사용에서 콩을 얻는 경우 :

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

문제는 DAO의 구현 코드에 @Transactional 주석의 사용은 봄이 JDK dynamic proxy을 만드는 것을 의미한다는 사실에 의해 발생 이를 위해 구현 클래스에 캐스트 할 수 없습니다. Here은 Spring의 AOP 기능 (JDK 동적 프록시 및 CGLib 클래스 프록시의 작성이 완전히 설명 된)의 전체 문서입니다.당신은 당신이 다시하지 않는 context.getBean("evntDAO") 호출 할 때

무슨 본질적 의미하는 것은, 그 때문에 @Transactional의 당신의 EventDaoImpl (사람이 기대하는 것처럼)하지만, 실제로 그 클래스 Spring에 의해 생성 된 java.lang.reflect.Proxy 인 객체를 다시 얻을 . 이 프록시 객체는 EventDao을 구현하지만 (그에 따라 캐스트 될 수는 있지만) 서명은 EventDaoImpl과 아무 관련이 없습니다 (따라서 EventDaoImpl을 확장하지 않으므로 ClassCastException). 프록시에서 메소드가 호출되면 호출이 실제로 EventDaoImpl에 위임되기 전이나 후에 (실제로는 EventDaoImpl에 대한 실제 호출이 InvocationHandler의 구현을 통해 스프링에 의해 제어 된 후에) 어떻게됩니까?

+0

위대한 .. 작동 했어. "이 트랜잭션 코드에서 @Transactional을 사용하면 Spring이 JDK 프록시를 생성한다는 것을 의미한다." –

+0

@BhargavKumarR 문제 없습니다! 내가 그 순간에 모바일 장치에 있기 때문에 나는 나중에 더 많은 정보로 내 대답을 업데이트 할 것이다 – geoand

+0

지리적 위치를 기다리고있을 것입니다 .. –

관련 문제