Business logic before to save an entity in Spring JPA - spring

I'm using Spring Boot 1.5.4, Spring Data REST, Spring JPA, Hibernate and I'm developing a Angular client consuming REST API.
Spring Data REST helps a lot and I'm trying to follow best practice, so a repository is like:
#Transactional
#PreAuthorize("isAuthenticated()")
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
}
and automagically I've all my save(), delete(), findXX() methods. That's great.
Now I'm wondering how if I need custom business logic to do before the entity is saved. let's say I need to do some kind of complex validation (involving queries on the db), and other backstage activities (maybe saving related entities, updating related objects, ect).
My goals are:
Ensure every time the entity is saved (either from a REST call or a JPA call) my business logic is called before the object is saved
Avoid to create a custom repository because a developer could call the standard repository breaking my rules
Find a way to do this in a simple way in order to keep the app easy to mantain
The #RepositoryEventHandler is not enough for me because I want ensure my business logic is always verified even when the call to the method come from internal classes.
Could you suggest me the best approach to reach my goals?

JPA has a bunch of entity listener.
#PrePersist Executed before the entity manager persist operation is actually executed or cascaded. This call is synchronous with the persist operation.
#PreRemove Executed before the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation.
#PostPersist Executed after the entity manager persist operation is actually executed or cascaded. This call is invoked after the database INSERT is executed.
#PostRemove Executed after the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation.
#PreUpdate Executed before the database UPDATE operation.
#PostUpdate Executed after the database UPDATE operation.
#PostLoad Executed after an entity has been loaded into the current persistence context or an entity has been refreshed.

Related

Spring Boot - Different Testing approaches

I've been working with Spring and Hibernate for about two years. Recently I have also been working on testing. Now I'm not quite sure if I understood everything correctly. Do I understand correctly that the following methods exist? **If I make wrong assumptions, please correct me!
Method 1:
Situation: The test class is annotated with #Transactional. The test data is created manually in an #BeforeEach method and stored in a repository.
Advantages: Through #Transactional annotation, all (BeforeEach, Test-Method, AfterEach) methods are executed in one transaction, which can be undone directly by rollback and therefore no emptying of the database is necessary.
Disadvantages: Since everything is carried out in one transaction and canceled directly by rollback, the data never ends up correctly in the database? Perhaps errors would occur during a commit? This means that the test does not reflect a real situation.
Method 2:
Situation: The test class has no #Transactional annotation. The test data is created and stored in an #BeforeEach method.
Advantages: Since the #Transactional annotation is missing, all calls of the service or controller are executed in a separate transaction, reflecting a real situation.
Disadvantages: Since everything is executed in separate transactions, the database must be completely emptied manually after each test (disable constraints and empty each table).
I have another question, but it's more subjective Do you like the initialization of test data using the #BeforeEach method and manual creation of objects and saving via repository or SQL scripts in #Sql annotation better? Initializing via SQL scripts feels faster in my opinion.

Is Repository the only way to save entity data on DB?

I'm studying Spring boot, and i have create several entity, my problem now is to retrieve the data from controller to save it on db.
Surfing on the web I have learned that i have to use JPARepositery or CrudRepositery in this way:
An example with User entity
public interface UserRepository extends CrudRepository<User, Integer> {
}
and to save
User user = new User();
userRepository.save(user);
But if I have many entities, Do I need to create a repository for each entity?
I have read about Session, FactorySession and Transaction they are compatible with Spring boot? How it works? and #Transactional tag how it works?
Thanks in advance
Yes, usually you need to create one Repository per Entity. This is also a good practice because you are placing operations and queries related to the same Entity in the same Repository.
Yes, you can obtain a Session and a FactorySession object (Hibernate), but I would advice you against using Hibernate directy. Instead, it is better to use Spring Data or JPA mechanisms to access your database (just as you do using a Repository). The reason is because Hibernate is an implementation of the JPA standard and today we use JPA to access databases (because it masks the exact implementation of the ORM). This way you can later (potentially) replace Hibernate with another JPA implementation (such as EclipseLink) without the need to change your code (in theory). In most projects you will find Hibernate being used, however.
Yes, Transaction is a Spring annotation and an important database transaction mechanism in Spring Boot, too.

Execute a method once every transaction begins inside methods annotated with spring - #Transactional

I want to make a database call before every method within my Spring application annotated with #Transactional started executing transaction.
There are few requirements for this:
This database call has to be part of the actual transaction that is about to begin.
The database connection used for the Transaction has to be same to be used for this database call and should setup some database data before 'real' transaction begins.
Is there something that Spring supports to achieve this goal ? One way I am thinking is to write own Aspect cloning more or less all Transactional code as is. Other way is to write Aspect. Not sure if there are more ways.

Spring-Cloud, Hystrix and JPA - LazyInitializationException

I have the following problem trying to integrate Hystrix into an existent Spring Boot application. I am using boot with spring data (jpa repositories). The structure of the app is pretty simple,
we have Resources -> Services -> Repositories.
I enabled Hystrix support and annotated one of the service methods that returns an entity as follow:
#HystrixCommand(fallback="getDealsFallback")
public Page<Deal> getDeals(...) {
// Get the deals from the Index Server.
return indexServerRepository.findDealsBy(...);
}
public Page<Deal> getDealsFallback(...) {
// If IndexServer is down, query the DB.
return dealsRepository.findDealsBy(...);
}
So this works as expected, the real problem resides actually when I return the Entity to the client. I am using OpenEntityManagerInViewFilter so I can serialize my model with its relations.
When I use #HystrixCommand in my service method, I get a LazyInitializatioException when It tries to serialize.
I know the cause (or at least I suspect what is the problem), and is because Hystrix is executing in another thread
so is not part of the transaction. Changing the Hystrix isolation strategy from THREAD to SEMAPHORE, works correctly since its the same thread, but I understand that is not the correct way to approach the problem.
So my question is, How can I make the Hystrix executing thread be part of the transaction. Is there any workaround that I can apply?
Thanks!
It is a little old thread, but maybe someone meets this problems too. There is an issue in github about this.
The reason is, hystrix will run in separate thread, which is different from where the previous transaction is. So the transaction and serialization for lazy will not work.
And the 'THREAD' is the recommended execution strategy too. So if you want to use both hystrix and transaction, you should use them in 2 level calls. Like, in first level service function, use transaction, and in second level service function, use hystrix and call first level transactional function.

Where should "#Transactional" be placed Service Layer or DAO

Firstly it is possible that I am asking something that has been asked and answered before but I could not get a search result back. We define transactional annotations on service layer typical spring hibernate crud is usually
Controller->Manager->Dao->Orm .
I now have a situation where I need to choose between the domain model based on client site.
Say client A is using my domain model all is good but then an other client site would give me a web service and not be using our domain model.
Which layer should I be replacing . I believe it has to be DAO which will be getting me data from web service and sending it back.i.e two separately written DAO layers and plugged in based on scenario.
I have now realized that we have been doing tight coupling (if there is such a thing or say not having loose coupling) when we put #Transactional in Service layer. So many brains can not be wrong or are they (I doubt it).
So question is "Where should "#Transactional" be placed Service Layer or DAO ?" and is it service layer downwards I should be replacing.
Eleven years on and still relevant . If I look back at the project somethings were obviously wrong with my understanding of Domain model back then . I was regarding ORM layer as domain model and we wanted to work with ORM and detached entities and no have any data mapping and not have any DTOs. That was the trend those days. These days Domain Model is not the ORM and having a proper Domain model and using ORM or Webservices are datasources take care of this issue. Like many pointed out yes Service is the right place for it and have proper domain model and not regard JPA (ORM) as domain model.
Ideally, Service layer (Manager) represents your business logic and hence it should be annotated with #Transactional.
Service layer may call different DAOs to perform DB operations. Lets assume a situation where you have 3 DAO operations in a service method. If your 1st DAO operation failed, other two may be still passed and you will end up with an inconsistent DB state. Annotating Service layer can save you from such situations.
You are going to want your services to be transactional. If your DAOs are transactional, and you call different DAOs in each service, then you would have multiple transactions, which is not what you want. Make the service calls transactional, and all DAO calls inside those methods will participate in the transactions for the method.
i will suggest to put #Transactional in Service layer methods since we can have multiple DAO implementations. by using this we can made our services will be transactional. refer
best practice is to use A generic BasicService to offer common services.
The Service is the best place for putting #Transactional, service layer should hold the detail-level use case behavior for a user interaction that would logically go in a transaction. in this way we can have maintain separation between web application code and business logic.
There are a lot of CRUD applications that don't have any significant business logic, for them having a service layer that just passes stuff through between the controllers and data access objects is not useful. In these cases we can put transaction annotation on Dao.
So in practice you can put them in either place, it's up to you.
By having multiple calls in your service you need #Transactional in service. different calls to service will execute in different transactions if you put #Transactional in service.
It's of a personal choice based on application types, if application is layerd across many modules and majority of operations are #CRUD based ,then having #transactional annotation at service level makes more sence.. engine type application like schedulers , job servers,#etl report apps, where sessions and user concept does not exists, then propagational transaction at context level is most suitable... we should not end up creating clusterd transactions by putting #transactional every where ending up transactional anti patters...anyways for pragmatic transaction control JTA2 is most suitable answer...again it depends on weather you can use it in a given situations...
You should use #Transactional at service layer, if you want to change the domain model for client B where you have to provide the same data in a different model,you can change the domain model without impacting the DAO layer by providing a different service or by creating a interface and implementing the interface in different model and with the same service populate the model based on the client.This decision is based on the business requirement and the scope of the project.
i have heard in a programming class,that dao layer is responsible for interacting with database, and service is a set of operations might be with dao and therefore database or not and that set of operation is in one transaction, mean is better service be transactional.

Resources