2017-01-08 2 views
0

私のアプリケーションでは、サービス層があります。これは、DAO層を扱う多くのREST Webサービスであり、データベース表を表すエンティティで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レイヤーを呼び出すことができます。また、各呼び出しは1つのHibernateトランザクションで処理されるため、1つの操作が失敗すると他の操作は実行されません。たとえば、請求書を作成して顧客の債務を更新するようにコードに指示しています。私はそれが請求書を作成し、債務を更新していないことが分かりました。私はいくつかの本を調べて、すべての操作を単一のトランザクションで処理し、何かが失敗した場合にそれらをロールバックする必要があると言いました。私はこれをやろうとしていますが、それは私が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

...他のトランスポート層(SOAP、...)に暴露され、テストすることができ、それは、コードを作業し、ちょうどあなたがそのすべてを逃した – SteelToe

+2

最適化が必要とされるコードレビューでこれを投稿してくださいSpringは、依存性注入、および自動の宣言的なトランザクション管理に役立ちます。 Springのドキュメントを実際に読んでください。トランザクションサービスのために必要なのは、 '@ Transactional'アノテーションだけです。 DAOインスタンスを取得する必要があるのは、サービスコンストラクタまたは非静的フィールドの '@ Autowired'です。また、Hibernateエンティティが管理されているという事実も見逃しました。セッションから取得したエンティティでsave()を呼び出すことは無意味です。そして、BTW、save()は新しい永続インスタンスを作成するためのものです。 –

+0

DAOからArrayListに渡したリストをキャストすることはまったく役に立たず、実際にコードを失敗させる可能性があります。 –

答えて

0


は、あなたがのDAOを使用してビジネス・ロジックを実装し、REST層などに依存性注入を経て、そのレイヤーを使用し、純粋なサービス層を追加します

@Path("/customers") 
public class CustomerService { 
    private Service service; 

    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    public List<Customer> getAllCustomersService() { 
     return (ArrayList<Customer>) service.getAllCustomers(); 
    } 
... 

サービス層を容易

+0

申し訳ありません、あなたのコメントのためにみんなありがとう。私はこのすべてをやろうとします。 –

関連する問題