@Transactional注释导致实体上出现不兼容的返回类型错误

时间:2011-09-21 12:19:23

标签: java hibernate spring spring-transactions

我在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;]

关于这个错误的奇怪部分是系统在注释被添加到类之前编译好并且按照预期编译,但是因为我需要能够将实体持久化到数据库,所以事务是必需的。我知道这个错误意味着什么,但是我不知道为什么这只是一个问题,当使用注释时,甚至没有应用于编译器抱怨的方法。

Advisors 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" />

1 个答案:

答案 0 :(得分:0)

添加注释不能更改返回类型。

首先,您可能导入了错误的类型 - Advisor也是一个弹簧类,因此请修复您的导入。

然后我怀疑你有一个旧版本的接口或它的实现,由类加载器加载。异常消息表明其中一个方法返回List<Advisor>,另一个方法返回Advisor[]。确保所有内容都已清理并保持最新状态。