在我的应用程序中,我有一个服务层,它是许多REST Web服务,它处理DAO层以对表示数据库表的实体执行CRUD操作。我在DAO层使用Hibernate。我的服务层Java类的一个例子是:
@Path("/customers")
public class CustomerService extends SessionUtil implements Service {
public static CustomerDao customerDao = (CustomerDao) context.getBean("customerDAO");
public static CustomerDebtDao customerDebtDao = (CustomerDebtDao) context.getBean("customerDebtDAO");
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Customer> getAllCustomersService() {
return (ArrayList<Customer>) customerDao.getAllCustomers();
}
@GET
@Path("/{start}/{end}")
@Produces(MediaType.APPLICATION_JSON)
public List<Customer> getCustomerBatchService(@PathParam("start") int start, @PathParam("end") int end) {
ArrayList<Customer> customers = (ArrayList<Customer>) customerDao.getCustomerBatch(start, end);
return customers;
}
@GET
@Path("/count")
@Produces(MediaType.APPLICATION_JSON)
public int getTotalRowCountService() {
return (int) customerDao.getTotalRowCount();
}
@GET
@Path("/{customerId}")
@Produces(MediaType.APPLICATION_JSON)
public Customer getCustomerService(@PathParam("customerId") int customerId) {
Customer customer = (Customer) customerDao.getCustomer(customerId);
return customer;
}
@POST
@Path("/create")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response createCustomerService(Customer customer) {
customerDao.createCustomer(customer);
return response;
}
@DELETE
@Path("/{customerId}")
@Produces(MediaType.APPLICATION_JSON)
public Response deleteCustomerService(@PathParam("customerId") int customerId) {
customerDao.deleteCustomer(customerId);
return response;
}
@PUT
@Path("/{customerId}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response editCustomerService(Customer customer) {
customerDao.editCustomer(customer);
return response;
}
...
}
DAO层的一个例子是:
public class CustomerDaoImpl extends JdbcDaoSupport implements CustomerDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public void createCustomer(Customer customer) {
customer.setCustomerId(getNextCustomerId());
customer.setCreated(new Date());
customer.setCustomerId(getNextCustomerId());
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(customer);
try {
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
}
@Override
public void editCustomer(Customer customer) {
Session session = sessionFactory.openSession();
session.beginTransaction();
session.update(customer);
try {
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
}
}
问题是,在服务层中,我有时会对DAO层进行多次调用,如您所见,每次调用都在一个Hibernate事务中处理,导致如果一个操作失败,其他操作将不会被执行。例如,我告诉代码创建发票然后更新客户的债务。我发现它创建了一张发票并且没有更新债务。我查看了几本书,他们都说我应该在一次交易中处理所有操作,如果有任何失败则回滚。我试图这样做,但它导致我几乎删除了整个DAO层,服务层变得庞大,难以理解且无法维护。一个例子如下:
@POST
@Path("/create")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response createSalesInvoiceLineService(SalesInvoiceLine salesInvoiceLine) {
Session session = sessionFactory.openSession();
session.beginTransaction();
// prepare sales invoice line object
salesInvoiceLine = salesInvoiceLineDao.createSalesInvoiceLine(salesInvoiceLine);
session.save(salesInvoiceLine);
updateSalesInvoiceAmountForCreate(salesInvoiceLine, session);
// update stock
Stock stock = stockDao.getStockByProduct(salesInvoiceLine.getProductId());
stock.setQuantity(stock.getQuantity().subtract(salesInvoiceLine.getQuantity()));
stockDao.editStock(stock);
session.save(stock);
// update debt
SalesInvoice salesInvoice = salesInvoiceDao.getSalesInvoice(salesInvoiceLine.getSalesInvoiceId(), session);
List<CustomerDebt> customerDebtList = customerDebtDao.getCustomerDebtByCustomerId(salesInvoice.getCustomerId());
CustomerDebt customerDebt = customerDebtList.get(0);
customerDebt.setAmount(customerDebt.getAmount().add(salesInvoiceLine.getLineAmount()));
Date date = new Date();
java.sql.Date currentDate = new java.sql.Date(date.getTime());
customerDebt.setUpdateDate(currentDate);
customerDebtDao.editCustomerDebt(customerDebt);
session.update(customerDebt);
try {
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
session.close();
}
return response;
}
答案 0 :(得分:0)
除现有评论外:
添加使用DAO实现业务逻辑的纯服务层,并通过REST层中的依赖注入使用该层,例如
resolve
服务层可以轻松测试,暴露给其他传输层(SOAP,..)......