服务层变得复杂且无法维护

时间:2017-01-08 20:07:33

标签: java spring hibernate rest

在我的应用程序中,我有一个服务层,它是许多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;
}

1 个答案:

答案 0 :(得分:0)

除现有评论外:
添加使用DAO实现业务逻辑的纯服务层,并通过REST层中的依赖注入使用该层,例如

resolve

服务层可以轻松测试,暴露给其他传输层(SOAP,..)......