You can use this Tutorial to understand how to add business logic to a Spring Data project, from scratch. The entire project can be completed in under 20 minutes.
This is Part I
, where we create a project with Domain Objects, sample data. We will test not with a User Interface, but rather by some jUnit tests (ala TDD
- Test Driven Development - prepare your tests before implementation). Completing Part I (requires about 5 minutes) prepares you for Part II
, where we add business logic to the project created here.
Background: Data Access and Business Logic
In any database-oriented application, you must provide data access APIs to read / write your data, and business logic to ensure that data is properly derived and constrained.
provides Java-oriented APIs to read / write Domain Objects (POJOs - Plain Old Java Objects) to relational databases. This is an important advance over jdbc, providing key features such as POJO-based access
(as distinct from clumsy string arrays used by jdbc), and relational mapping
, so your POJOs can utilize Java features such as inheritance).
Hibernate is fine for many applications, but there are many cases where you wish to hide the Hibernate APIs, for example for discoverability, or to enable your application to be retargeted to noSql engines. Spring Data
provides an excellent approach wherein simple interface definitions generate Repository Objects that present a pure Java api for data access.
But you still must implement the business logic, which presents issues that directly affect business agility and TCO:
- Time: logic is built manually, without automation tools such as UI frameworks. So, the 5 simple requirements shown here result in 500 lines of code. Rete-based Business Rule Engines don't provide active enforcement of logic, and deal poorly with aggregates (sums and counts).
- Complexity: debates persist - Anemic Domain Objects? Services Layers? Logic-enhanced Domain Objects? Data Access Objects?
ABL is designed to enable you to build your business logic with competitive advantages in agility, TCO and transparency, operating as follows:
- Familiar annotations declare multi-table logic, somewhat like spreadsheet formulas. Annotations are powerful (each representing 100+ lines of code), yet so simple they are transparent to both IT and Business Users. Annotations address over 95% of your logic, and you can use Logic Methods to address more complex requirements.
- The ABL Logic Engine plugs into Hibernate events - since you don't directly call the logic, you do not need to recode your application, and integrity / re-use is assured. The engine automates multi-table execution order based on dependencies, so that development cycles and maintenance simple entail simply changing the logic, without the tedious archaeology to decipher existing code.
This short tutorial illustrates how you can utilize Spring Data for pure Java API, and use ABL declarative annotations for complex, multi-table business logic.
|This tutorial introduces the following key concepts: |
- @Logic - how to define Logic Classes and Logic Annotations
- Complex multi-table logic - how your logic addresses complex, multi-table logic
- Automated Dependency Management - how logic dependencies are detected and automated
- Object Declarative - how you can use Java/Groovy Logic Methods for complexity and extensibility
- Assured Re-use / Integrity - how the Business Logic Engine ensures your logic is re-used
- Logic Debugging - how to verify your logic is operating properly
In this Tutorial, we will build a small Customer, PurchaseOrder, LineItem and Product application from scratch. The bottom of this page includes several zip files provided to save typing.
Our focus is on the business logic, persistence or IDE. Our business logic objectives, captured on the obligatory cocktail napkin:
|The requirements are enforced over a series of Use Cases that touch this data:|
- Adding and changing new PurchaseOrder and their LineItems
- Making an PurchaseOrder ready, or paid
- Reassigning a PurchaseOrder to a different Customer
- Changing LineItem quantities, or reassigning to different Products
Of course, a Data Model and User Interface is required for logic execution. For these, we will utilize Spring Grails since it provides default services for those elements, using Groovy. You can perform a similar tutorial in a wide variety of other IDEs and frameworks.
This tutorial presumes a basic understanding of Hibernate/JPA and Java. It does not presume a strong background in STS or Spring Data.
- You will need SpringSource Tool Suite (STS), as explained here. STS is an extended version of Eclipse, which includes elements required for this demo.
- You also need to verify proper operation of Spring Data, as described here.
Install and verify the demo as described below.
Create a folder for the workspace:
BusLogicDemo Spring Data WS
We'll use this in the steps below.
BusLogicDemo Spring Data project
Download and unzip the
BusLogicDemo Spring Data (use the download arrow link at the bottom of this page) into the folder created above. You will get a folder with the same name as the zip
, as shown in the diagram below.
BusLogicDemo Spring Data Project
- Open the workspace
BusLogicDemo Spring Data WS in STS
- Import > Existing Maven Project > BusLogicDemo Spring Data project from the previous step
- Important: you may encounter errors - correct them as described under the previous Prerequisites section.
Use the diagram below to confirm your folder structure (this screen shot was taken after the project import, which creates the
Verification: Run the jUnit Test
To run the jUnit test, right click on
VerifyInstall, and select Debug as > Junit test. It should pass.
How the Project was built
The sub-sections below describe how the project was built.
Defining Domain Objects
These are completely standard. Note the top panel in the diagram below, using the
Defining Repository Objects
The steps to build a Repository object (such as CustomerRepository) were:
- Define the interface (
CustomerRepository) that specifies the NamedQuery. It extends Spring-supplied
CrudRepository to inherit definitions of methods such as
save(), used above in the jUnit test
- Register the base packages in
- Standard JPA Domain Objects (here,
Customer), with the @NamedQuery annotation as shown below
- Configure Spring Data as shown in
repository-context.xml, referenced in
- You must also configure
infrastructure.xml to denote the persistance unit in
persistence.xml, as we'll see in Part II
Spring Data Magic
As you can see from the screen shot above, there is no implementation. The Spring Data services built the executable
SimpleCustomerRepository class from the interface definition. As shown in the jUnit code, this object provides executable implementations to read 1 / many Customer instances, and perform crud (create, read, update and delete) operations via discoverable Java APIs.
The sample project includes 3 jUnit tests:
VerifyInstall (introduced above) simple verifies that basic JPA / Repository operations execute on the in-memory database
BusLogicDemoJPA performs crud operations to create, read, update and delete a Purchase order, using JPA APIs
BusLogicDemoRepository includes the crud functions using Repository APIs
The latter tests verify business logic which is not yet defined - we'll do that in Part II.
Project Creation Complete - Part I
You now have a simple, but complete, Spring Data project, including a database schema and a web interface.
Well, maybe not that complete! The business logic - see our cocktail napkin above - is totally missing. This is first apparent from the loaded data (all the Customer balances are 0), and continues to be missing if you create, update or delete orders.
Not to fault Spring Data - frameworks simply aren't built to address this element of your app. The problem is, this is about half the app (even more as framework automation increases).