我正在尝试减少应用程序的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;
我不明白的是,我只需要在测试中执行此操作 - 程序在没有该注释的情况下在服务器上运行良好...