tse*_*han 7 orm spring annotations hibernate java-ee
我测试我的DAO,但它没有用.发生以下错误:
Tests in error:
testAccountOperations(com.tsekhan.rssreader.dao.HibernateControllerTest): Error creating bean with name 'com.tsekhan.rssreader.dao.HibernateControllerTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.tsekhan.rssreader.dao.HibernateController com.tsekhan.rssreader.dao.HibernateControllerTest.hibernateController; nested exception is java.lang.IllegalArgumentException: Can not set com.tsekhan.rssreader.dao.HibernateController field com.tsekhan.rssreader.dao.HibernateControllerTest.hibernateController to $Proxy25
Run Code Online (Sandbox Code Playgroud)
我的DAO:
@Service
@Scope("singleton")
public class HibernateController extends HibernateDaoSupport {
@Autowired
public SessionFactory sessionFactory;
@Transactional
public void addAcount(Account account) {
sessionFactory.getCurrentSession().saveOrUpdate(account);
}
}
Run Code Online (Sandbox Code Playgroud)
我对这个DAO的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/applicationContext.xml")
public class HibernateControllerTest {
@Autowired
HibernateController hibernateController;
private Set<Channel> getTestChannelList(String channelLink) {
Channel testChannel = new Channel();
testChannel.setSourceLink(channelLink);
Set<Channel> testChannelList = new HashSet<Channel>();
testChannelList.add(testChannel);
return testChannelList;
}
private Account getTestAccount(String accountLogin, String channelLink) {
Account testAccount = new Account();
testAccount.setAccountLogin(accountLogin);
testAccount.setChannelList(getTestChannelList(channelLink));
return testAccount;
}
@Test
public void testAccountOperations() {
hibernateController
.addAcount(getTestAccount("test_login", "test_link"));
}
}
Run Code Online (Sandbox Code Playgroud)
我的applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd"
default-autowire="byName">
<!-- Enabling spring-transaction annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Enabling annotation-driven configurating -->
<context:annotation-config />
<!-- Creation of transaction manager -->
<bean id="transactionManager" scope="singleton"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory" scope="singleton"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation" value="classpath:/hibernate.cfg.xml"/>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<!--
A Spring interceptor that takes care of Hibernate session lifecycle.
-->
<bean id="hibernateInterceptor"
class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean name="employeeDAO" scope="prototype"
class="com.tsekhan.rssreader.dao.HibernateController" />
<!-- Searching for hibernate POJO files in package com.tsekhan.rssreader.web -->
<context:component-scan base-package="com.tsekhan.rssreader.web" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
</beans>
Run Code Online (Sandbox Code Playgroud)
我注意到,如果您在DAO中注释@Transactional,则会正确创建bean.怎么了?
bab*_*ira 22
首先,它真的很难将名称以Controller结尾给DAO,它非常令人困惑,Controller和DAO都有不同的目的.
当你添加@Transactional
到一个服务或dao类时,对于spring来说它在一个事务中工作需要创建该类的代理,它是一种包装器,它在执行代理类之前(代理的类代理)方法spring启动事务并在执行后如果没有异常完成事务,这可以在Spring中通过AOP和Annotations完成.在代码中描述.
public class OriginalDaoImpl implements OriginalDao extends DaoSupport {
public void save(Object o){
manager.save(o);
}
}
public class ProxyDaoImpl implements OriginalDao {
private OriginalDao originalDaoImpl; //instance of OriginalDaoImpl
public void save(Object o){
try{
transaction.start();
originalDaoImpl.save(o);
transaction.commit();
}catch(Exception e){
transaction.rollback();
}finally{
//clean up code
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,这不是一个确切的实现,而是一个基础代码,交易如何神奇地为您服务.关键点在于接口OriginalDao使得这种注入变得容易,因为OriginalDaoImpl和ProxyDaoImpl都实现了相同的接口.因此,它们可以被交换,即代理取代原始.可以通过Java动态代理在Java中创建此动态代理.现在,问题是如果你的类没有实现一个接口,更换就会变得更难.据我所知,其中一个库CGLIB在这种情况下有所帮助,它为这个类生成一个动态子类,并且在overriden方法中通过调用super.save(o)
委托给原始代码来执行上述魔术.
现在来注射的问题.
proxy-target-class="true"
属性<tx:annotation-driven transaction-manager="transactionManager"/>
就异常而言,它正在抛出,因为它期望注入的bean是'HibernateController'类型但不是.
有关您的参考,请参阅以下链接.
希望这可以帮助 !!!!!.
归档时间: |
|
查看次数: |
11125 次 |
最近记录: |