我有一个在 Spring MVC 中开发的 Restful Web 服务,它当前返回农民信息,并允许在数据库中删除和添加新农民。在扩展 Web 服务以包含农民顾问时,只要将事务注释添加到顾问 DAO 实现,我就会收到以下错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'advisorDAO' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: methods with same signature getAdvisors() but incompatible return types: [interface java.util.List, class [Lorg.springframework.aop.Advisor;]
关于这个错误的奇怪部分是,在将注释添加到类之前,系统编译得很好并且符合预期,但是因为我需要能够将实体持久化到数据库中,所以需要事务。我知道错误的含义,但我不知道为什么这只是使用注释时的问题,甚至没有应用于编译器抱怨的方法。
顾问 DAO 界面:
public interface AdvisorDAO {
public List<Advisor> getAdvisors();
public Advisor getAdvisorByPk(int id);
public Advisor getAdvisorByFarmerID(int id);
public Advisor getAdvisorByAdvisorID(int id);
public void saveAdvisor(Advisor advisor);
public void deleteAdvisor(Advisor advisor);
public void updateAdvisor (Advisor advisor);
}
接口实现:
public class JpaAdvisorDAO implements AdvisorDAO {
@PersistenceContext
private EntityManager entityManager;
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public List<Advisor> getAdvisors() {
return entityManager.createNamedQuery("Advisor.findAll").getResultList();
}
@Override
public Advisor getAdvisorByPk(int id) {
Query query = entityManager.createNamedQuery("Advisor.findByPK");
query.setParameter("advisorPk", id);
return (Advisor) query.getSingleResult();
}
@Override
public Advisor getAdvisorByFarmerID(int id) {
Query query = entityManager.createNamedQuery("Advisor.findByFarmerId");
query.setParameter("farmerId", id);
return (Advisor) query.getSingleResult();
}
@Override
public Advisor getAdvisorByAdvisorID(int id) {
Query query = entityManager.createNamedQuery("Advisor.findByAdvisorId");
query.setParameter("advisorId", id);
return (Advisor) query.getSingleResult();
}
@Override
@Transactional
public void saveAdvisor(Advisor advisor) {
entityManager.persist(advisor);
}
@Override
@Transactional
public void deleteAdvisor(Advisor advisor) {
entityManager.remove(entityManager.getReference(Advisor.class, advisor.getAdvisorPk()));
}
@Override
@Transactional
public void updateAdvisor (Advisor advisor) {
entityManager.merge(advisor);
}
使用的上下文文件:
<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc">
<bean id="farmerDAO" class="com.test.cmsservice.persistance.JpaFarmerDAO" />
<bean id="advisorDAO" class="com.test.cmsservice.persistance.JpaAdvisorDAO" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="SpringRestService"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
<property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect"/>
</bean>
</property>
</bean>
<context:annotation-config />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="url" value="jdbc:derby://localhost:1527/SpringDBTest"/>
<property name="username" value="APP"/>
<property name="password" value="app"/>
</bean>
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="persistenceAnnotation" class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />