Domain and service methods for banking transaction - spring

I am trying to learn Spring framework and see the many of the examples use domain and service objects (domain-driven design?) but I am not able to really understand how to arrive at them. For example, I am trying to model a simple banking application which has customers,accounts and transactions. Below is the draft model i have:
Domain objects:
Customer
id
userName
password
Account:
id
customerId
balance
Transaction:
id
accountId
amount
transactionDate
transactionType
Service objects:
AccountService:
create(Account)
update(Account)
debit(Account,amount,date,remarks)
credit(Account,amount,date,remarks)
transfer(fromAccount,toAccount,amount,remarks)
findAccountsByCustomerId(customerId)?
CustomerService:
findCustomerByName()
findAccountsByCustomerId(customerId)?
Should the CustomerService or AccountService have the method findAccountsByCustomerId(customerId)?
Which domain/service objects should represent the debit/credit transaction? debit() and credit() methods in Account domain object to be defined or in the service object? I would like to persist the transactions rather than just updating the balance.
Should all the business logic be in Service layer? I see most of the spring examples out there are this way.

Since the idea here is to retrieve Accounts, it should be in
AccountService.
Both methods looks fine in AccountService to me because you're
operating on accounts. If you want to persist the transaction you
could have a TransactionDao handling this for you and you'd be
calling it from your AccountService each time you need it. Doing
both in your AccountService methods will allow you to be
transactional. You don't want to persist the transaction object if
updating the balance raised an exception.
Services are useful when you have business logic which does not
belong in your DAO layer. The latter is supposed to query your
database and give you back appropriate domain objects whereas
services are mostly used to do additional treatments like handling
transactions or DTO mapping.
You should take a look at the official Spring sample app PetClinic to give you an idea.

Related

diffrence between persistence layer and bussiness logic layer

Persistence layer is a group of files which is used to communicate between the application and DB. 2. Business logic layer is the rules of how to retrieve the data information from the database, and then the sever takes those information to display on the user presentation layer
This two layers look the same
What do they mean in real scenario? Also do they have difference in code?
The idea for layering a system is isolation. One layer is independent of the other.
How many different Databases are out there? Postgresql, MySql, MongoDB, Cassandra...
The persistence layer (or Data Access Layer) will provide an interface to your your system.
Let's say you system needs to find an User by its ID.
public interface UserRepository {
User findByID (Long id);
}
For each database, the implementation will change, but for the application consuming it, does it really matter? No, as long as the contract provided by the interface is not broken.
Once you have the data, the business logic will dictate what and how you will deal with it. For a MVC point of view, the business logic also defines the transaction scope (more at: Why we shouldn't make a Spring MVC controller #Transactional?).
Let's say that you have your User that you retrieved using the previous interface. But you need to return additional attributes, for example, its salary. But there is no Salary Attribute on the User POJO. And also, to calculate the salary, you system needs to call an external system. Your business logic will take care of that and then return the condensed object (known as Data Transfer Obejct) to the caller.
Some resources:
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

#Transaction annotation between layers in Spring

What is the difference in using this #Transactional annotation in Domain/Service layer and Dao layer. Will it provide any advantage using in Domain layer.
It is good practice to use #Transactional in the service layer because it governs the logic needed to identify the scope of a database and/or business transaction. The persistence layer by design doesn't know the scope of a transaction.
DAOs can be made #Transactional like any other bean, but it's a common practice to use it in service layer. We tend to do this because we want separation of concerns. The persistence layer just retrieve / stores data back and forth from the database.
For example, if we want to transfer some amount from one account to another, we need two operations, one account needs to be debited other needs to be credited. So, the scope of these operation is only known by service layer and not persistence layer.
The persistence layer cannot know what transaction it's in, take for example a method person.updateUsername(). Should it run in it's own separate transaction always? there is no way to know, it depends on the business logic calling it.
Here a few thread you should read
Where does the #Transactional annotation belong?
Where should "#Transactional" be place Service Layer or DAO
The place you use #Transactional annotation specifies the scope of your transaction.
When using it in DAO layer you are specifying that each DAO operation will be committed in a transaction.
When using it in service you are specifying that each service operation (business unit) is committed in a transaction, this is recommended since usually service method represents a business unit which should be included in the same transaction since any failure should roll back the whole business unit.
#Transactional: There are two separate concepts to consider, each with it's own scope and life cycle:persistence context , database transaction
It look like u r more into database traction :
#Transactional annotation itself defines the scope of a single database transaction. The database transaction happens inside the scope of a persistence context.
The persistence context is in JPA the EntityManager, implemented internally using an Hibernate Session

Perform JSR 303 validation in transactional service call

I am using the play framework to develop a web application which accesses a postgres db using JOOQ and spring transactions.
Currently I am implementing the user signup which is structured in the following way:
The user posts the signup form
The request is routed to a controller action which maps all parameters like e-mail, password etc. on a DTO. The different fields of the DTO are annotated with JSR 303 constraints.
The e-mail field is annotated with a constraint validator that makes sure that the same address is not added twice. This validator has an autowired reference to the UserRepository, so that it can invoke it's isExistingEmail method.
The signup method of the user service is called, which basically looks as follows:
#Transactional(isolation = Isolation.SERIALIZABLE)
public User signupUser(UserDto userDto) {
validator.validate(userDto);
userRepository.add(userDto);
return tutor;
}
In case of a validation error the validator.validate(userDto) call inside of the service will throw a RuntimeException.
Please note that the repository's add method is annotated with #Transactional(propagation = Propagation.MANDATORY) while the isExistingEmail method does not have any annotations.
My problem is that when I post the signup form twice in succession, I receive a unique constraint error from the database since both times the userRepository.isExistingEmail call returns false. However, what I would expect is that the second signup call is not allowed to add the user to the repository, as I set the isolation level of the transaction to serializable.
Is this the expected behavior or might there be a JOOQ/spring transactions configuration issue?
I added a TransactionSynchronizationManager.isActualTransactionActive() call in the service to make sure a transaction is actually active. So this part seems to work.
After some more research and reading the documentation on transaction isolation in the postgres manual I have come to realize that my understanding of spring managed transactions was just lacking.
When setting the isolation level to SERIALIZABLE postgres won't really block any concurrent transactions. Instead it will make use of predicate locks to monitor if a committed transaction would produce a result that is different than actually running concurrent transactions one after another.
An exception will only be thrown by the underlying database driver if the state of the data is not valid when the second transaction tries to commit. I was able to verify this behavior and to force a serialization failure by temporarily removing the unique constraint on my e-mail field.
My final solution was to reduce the isolation level to READ_COMMITTED and to handle the unique constraint violation exception when invoking userRepository.add(userDto), since a SERIALIZABLE isolation level is not really necessary to deal with this particular use case.
Please let me know of any better ways of dealing with this kind of standard situation.

Domain, DAO and Service layers

I need to learn the difference between the type of methods (in term of business logic) that should be inside the Domain, DAO and Service layers objects.
For example, if I am building a small web application to create, edit and delete customers data, as far as I understand inside Domain layer object I should add methods that Get/Set Customers object properties, for example (getName, getDOB, setAddress, setPhone...etc).
Now what I am trying to learn is what methods shall I put in DAO and Service layers objects.
Thanks in advance for your time and efforts.
Speaking generally (not Hibernate or Spring specific):
The DAO layer contains queries and updates to save your domain layer into your datastore (usually a relational DB but doesn't have to be). Use interfaces to abstract your DAO away from the actual datastore. It doesn't happen often, but sometimes you want to change datastores (or use mocks to test your logic), and interfaces make that easier. This would have methods like "save", "getById", etc.
The Service layer typically contains your business logic and orchestrates the interaction between the domain layer and the DAOs. It would have whatever methods make sense for your particular domain, like "verifyBalance", or "calculateTotalMileage".
DAO: "wrapper" methods for "wrapping" JPA or JDBC or SQL or noSQL calls or whatever for accessing DB systems.
Domain: Business logic calls correlated to a single type of entities (domain objects).
Service: Business logic calls correlated to a group of type of entities or to a group of several entities of the same type.
(I'm not sure about English, sorry.......)
It means:
Service layer is "bigger" than Domain layer, is often close to front-end, often calls or uses several domain objects.
Domain objects encapsulate most stuff for one part of the domain (that's why they are called D.O.)
DAO is just sth technical, sometimes needed, sometimes not.
When real domain objects are used, then often "repositories" are used to hide access to database systems, or adding special db functionality or whatever.
front-end --> service method 1 --> d.o. A of type X, d.o. B of type X, List

What is a good example of a service layer in ASP.NET MVC?

i would love to know what is a good example (provide some code) of a service layer in ASP.NET MVC ?
What exactly it should include and contains ?
From what should it be decoupled ?
Thanks.
The service layer should contain business operations and it should be decoupled from the data access layer (repositories). The service layer exposes business operations which could be composed of multiple CRUD operations. Those CRUD operations are performed by the repositories. So for example you could have a business operation which would transfer some amount of money from one account to another and in order to perform this business operation you will need first to ensure that the sender account has sufficient provisions, debit the sender account and credit the receiver account. The service operations could also represent the boundaries of SQL transactions meaning that all the elementary CRUD operations performed inside the business operation should be inside a transaction and either all of them should succeed or rollback in case of error.
In order to decouple the service layer from the underlying data access layer you could use interfaces:
public class BankService
{
private readonly IAccountsRepository _accountsRepository;
public OrdersService(IAccountsRepository accountsRepository)
{
_accountsRepository = accountsRepository;
}
public void Transfer(Account from, Account to, decimal amount)
{
_accountsRepository.Debit(from, amount);
_accountsRepository.Credit(to, amount);
}
}

Resources