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

发布于 2024-12-06 06:31:23 字数 5119 浏览 0 评论 0原文

我有一个在 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" />

I have a Restful web service developed in Spring MVC which currently returns farmer information and allows for the deletion and addition of new farmers to the database. When extending the web service to include farmer advisors I am recieving the following error as soon as I add the transactional annotation to the advisor DAO implementation:

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

The odd part about this error is that the system compiles fine and as intended prior to the annotation being added to the class, however as I need to be able to persist the entity to the database the transactions are a requirement. I know what the error means but I am at a loss as to why this is only an issue when using the annotation which isn't even applied to the method the compiler is complaining about.

The Advisors DAO interface:

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);
}

The interface implementation:

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);
}

The context file used:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏了南城 2024-12-13 06:31:23

添加注解不能改变返回类型。

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

然后我怀疑您的接口或其实现是由类加载器加载的旧版本。异常消息表明其中一个方法返回 List,另一个方法返回 Advisor[]。确保所有东西都已清理干净并且是最新的。

Adding the annotation can't change the return type.

First, you have probably imported the wrong type - Advisor is a spring class as well, so fix your imports.

Then I suspect that you have an older version of your interface or its implementation that is loaded by the classloader. The exception message says that one of the methods returns a List<Advisor> and the other - Advisor[]. Make sure everything is cleaned and up-to-date.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文