预计单匹配bean但发现3

时间:2016-03-14 16:45:06

标签: hibernate spring-mvc interface

我正在尝试减少应用程序的DAO层的重复代码。 为了做到这一点,我创建了一个通用接口,其中包含我所有POJO使用的方法,并且可以扩展它。

public interface DaoInterface<T extends Object> {


    public void save(T object);

    public List<T> getList();

    public void deleteById(int id);

    public void update(T object);

    public T getById(int id);


}

那部分效果很好但是我遇到了另一个问题。 我有三个类(当然还有InvoiceEnergy,InvoiceGas和InvoiceWater),它们扩展了相同的抽象Invoice类。 尽管差别很小,但在调用数据库时,三者都有相同的方法。

而不是有三个非常相似的界面:

public interface InvoiceEnergyDAO extends DaoInterface<InvoiceEnergy> {

    public InvoiceEnergy getLatest();

    public List<InvoiceEnergy> getInvoicesForCalulation(Invoice invoice);

    public List<InvoiceEnergy> getUnpaidInvoices();

    public InvoiceEnergy getLastResolved();

    public void resolveInvoice(InvoiceEnergy invoice);

    public void unresolveInvoice(int id);

}

我创建了一个:

public interface InvoiceDao<I extends Invoice> extends DaoInterface<I> {

    public I getLatest();

    public List<I> getInvoicesForCalulation(Invoice invoice);

    public List<I> getUnpaidInvoices();

    public I getLastResolved();

    public void resolveInvoice(I invoice);

    public void unresolveInvoice(int id); }

我有三个实现(一个在下面):

@Repository("invoiceEnergy")
@Transactional
public class InvoiceEnergyDAOImpl extends AbstractDao<Integer, InvoiceEnergy> implements InvoiceDao<InvoiceEnergy> {



    @Override
    public InvoiceEnergy getLatest() {
        Query query = getSession().createSQLQuery(
                "select * from kamienica.invoiceenergy where date = (select MAX(date) from kamienica.invoiceenergy)");
        return (InvoiceEnergy) query.uniqueResult();

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<InvoiceEnergy> getInvoicesForCalulation(Invoice invoice) {
        Query query = getSession()
                .createSQLQuery(
                        "select * from kamienica.invoiceenergy where status = :status and date <= :date and baseReading_id is not null order by date asc")
                .addEntity(InvoiceEnergy.class).setParameter("date", invoice.getDate())
                .setParameter("status", PaymentStatus.UNPAID.getPaymentStatus());
        return query.list();

    }

(more code here.....)

一切似乎都很好,但是当我进行测试时,我得到了:

  

org.springframework.beans.factory.BeanCreationException:错误   创建名为'kamienica.dao.InvoiceGasDaoImplTest'的bean:   注入自动连接的依赖项失败;嵌套异常是   org.springframework.beans.factory.BeanCreationException:不能   autowire field:kamienica.dao.invoice.InvoiceDao   kamienica.dao.InvoiceGasDaoImplTest.invDao;嵌套异常是   org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有   定义了[kamienica.dao.invoice.InvoiceDao]类型的限定bean:   预计单匹配bean但发现3:   invoiceEnergy,invoiceGas,invoiceWater

我不明白是什么问题...我有多个接口成功扩展了DaoInteface但我在尝试扩展它时遇到错误。

编辑1

@Dragan 这是班级。最奇怪的是,新的解决方案(减少接口)在应用程序中运行良好,只在测试时崩溃....

public class InvoiceGasDaoImplTest extends EntityDaoImplTest {


    @Autowired 
    InvoiceDao<InvoiceGas> invDao;

    @Test
    public void findById() {
        Assert.assertNotNull(invDao.getById(1));
        Assert.assertNull(invDao.getById(2));
    }

    // @Test
    // public void save() {
    // invDao.save(getSampleMeter());
    // Assert.assertEquals(invDao.getList().size(), 5);
    // }

    // @Test
    // public void deleteById() {
    // invDao.deleteGasByID(5);
    // Assert.assertEquals(invDao.getList().size(), 4);
    // }

    // @Test
    // public void deletetByInvalidId() {
    // invDao.deleteGasByID(9);
    // Assert.assertEquals(invDao.getList().size(), 4);
    // }

    @Test
    public void findAll() {
        Assert.assertEquals(invDao.getList().size(), 1);
    }

    // @Test(expectedExceptions =
    // org.hibernate.exception.ConstraintViolationException.class)
    // public void saveDuplicate() {
    // invDao.save(getDuplcateNubmerApartment());
    // Assert.assertEquals(invDao.getList().size(), 4);
    // }

    public MeterGas getSampleMeter() {
        MeterGas meter = new MeterGas();
        meter.setApartment(null);
        meter.setDescription("test");
        meter.setSerialNumber("7676434211");
        meter.setUnit("test");
        return meter;
    }

    // private InvoiceGas getSampleInvoice() {
    // InvoiceGas invoice = new InvoiceGas("fsdfsd", description, date,
    // totalAmount, reading)
    // return null;
    // }

    public MeterGas getDuplcateNubmerApartment() {
        MeterGas meter = new MeterGas();
        meter.setApartment(null);
        meter.setDescription("test");
        meter.setSerialNumber("1");
        meter.setUnit("test");
        return meter;
    }
}

编辑2 我已经设法通过在每个Autowire之后添加@Qualifier来通过测试。 例如:

@Autowired
@Qualifier("invoiceWater")
InvoiceDao<InvoiceWater> invDao;

我不明白的是,我只需要在测试中执行此操作 - 程序在没有该注释的情况下在服务器上运行良好...

0 个答案:

没有答案