FlushMode in JPA with Spring - spring

I have some problems with FlushMode.AUTO in JPA/Hibernate, because i need change a value of a JavaBean and process a special validation. If validation is ok the bean is updated in DB, if validation fail the bean cannot be updated, like this:
MyBean bean = getBeanFromDB();
bean.setNewNumber(12);
//Before call isValid the bean already updated in DB
if (isValid(bean)){
update(bean);
}
But before validation begins, the Hibernate process the AUTO-UPDATE in my Bean and i don't wanna it. So my solution is setting FlushMode.COMMIT in JPA, but i'm using Spring and i don't know how can i do it in CONFIGURATION (XML) mode.

I see two options:
use bean validation (aka JSR-303) and its JPA integration to ensure automatic validity
use #PrePersist and #PreUpdate events to have your validation logic invoked automatically

Related

How does a spring converter get a transactional scope?

I was wondering, how a spring converter implementation gets an transactional scope.
Having a Converter which is used to convert a path placeholder (entity id) in an (rest) controller to the Entity itself. The Entity thus is loaded via Hibernate from the database.
For the details:
spring boot 2.3.2
A rest controller endpoint which triggers the converter to expand a path-placeholder (prior executing the rest-endpoint method body)
If in question, the controller method is not annotated #Transactional either
Question:
How (since we disabled OSIV) does this Converter get it's Transactional scope if the convert neither the method/nor the converter class is annotated using Transactional nor the convert method does custom transaction handling?
If you mean how Spring Data repositories get a transaction, the answer is all repository methods are transactional by default.

Why creation of repository beans need a datasource bean during start-up

I was working on a Spring-data-jpa project with spring boot, I see that the creation of repository beans required a datasoure bean to be present, Why is it so?
And can a repository bean be created without datasource bean.
The purpose of a repository is to load and save data into a persistent store.
Spring Data JPA does that using JPA so it needs an EntityManager which in turn need a DataSource.
Strictly speaking the DataSource is only used once the database is actually accessed.
While you definitely nee a DataSource bean you may delay the construction of a normal DataSource by providing a wrapper which instantiates the the actual DataSource at a later point in time.
DelegatingDataSource might be of help, either as a basis class or, since you are going to change the DataSource as a template for an implementation.
See the somewhat related question https://stackoverflow.com/a/61208585/66686

How To Execute method before #PostConstruct work??

I am Trying to update DB Schema whenever application version updated.
Some People said It is not a good Function but I wanna try whether I use it or not.
I Succeed Update schema when application booted.
but I have to change the timing that schema updated. and It is between after Bean object DI finished and before #PostConstruct work.
is it impossible, just before #PostConstruct work whether DI is finished or not.
how can I do this?
PS. I have known flyway work similar function compared I am making. but I want to make similar thing by my self.
When spring bean gets initialized, spring guarantees that all the properties will be injected (by means of applying constructor injection, setter injection or field injection)
So First of all spring calls bean's constructor
Then (if the fields are not set yet) it tries to inject fields
And only after that, it calls #PostConstruct
So you should be able to access the database from the post-construct method of the bean.

Hibernate JPA, Bean Validation, and Spring

How can I programmatically change the ParameterNameProvider used by my Spring + Hibernate JPA application?
I tried to create a validation.xml but I keep getting exceptions saying that "parameter-name-provider" is an invalid element.
So I figured I'd prefer to do it programmatically anyway, but I can't figure out how to modify the validator the system will use with my ParameterNameProvider.
I sounds to me that you are not using the right version of Bean Validation. If parameter-name-provider is an invalid element, you might be using the Bean Validation 1.0 API, instead of 1.1. Programmatically it looks for example like this:
ValidatorFactory factory = Validation
.byDefaultProvider().configure()
.parameterNameProvider( new MyParameterNameProvider() )
.buildValidatorFactory();
But again, you need Bean Validation 1.1.

hibernate validator without using autowire

I'am currently working on a Jersey project and decided to use Hibernate validator for the parameter validations. All dependencies injected on the Endpoint classes are properly initialized. However for those dependencies in the ConstraintValidator classes, it always throw a NPE. So i followed the guide on Spring+hibernate guide and registered
bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
and used the #Autowired annotation for the services in the ConstraintValidator class which needs to be injected.
are there side effects of using it? Is there a way to avoid the autowiring annotation in ConstraintValidator class and still injecting the values? I tried manually registering the constraintValidator class in the context as bean, adding a property reference to the service that i need, however it throws a null pointer exception.
"Hibernate Validator - JSR 303 Reference Implementation - Reference Guide" says something about portality:
Warning
Any constraint implementation relying on ConstraintValidatorFactory
behaviors specific to an implementation (dependency injection, no no-arg
constructor and so on) are not considered portable.
So, is it a bad thing? In my opinion it's not. Of course you are now coupled to the DI container (Spring) and can't easily reuse validators (e.g. when not using Spring). On the other hand, with your validators build by a Spring factory you can take full advantage of the framework and do very heavy lifting (read revision data for entities and comparison of previous states, call arbitrary services, enhance or localize validation messages, ...).
One thing you must be very careful about is that a validator's semantics is normally read-only and should not cause side-effects by calling it. For example don't accidentally flush data to the database because of some auto-flushing by invoking a (transactional) service or reading data inside your validator.

Resources