Spring Boot/JPA not persisting with service layer - spring

I'm using Spring boot along with Spring Data JPA.
I'm stucking in an odd scenario when saving a new entity.
Unsing method from extended CrudRepository class, all works as expected.
If I inject via #Autowired the CrudRepository interface in my service layer, the method still works, but nothing is persisted on db.
The returned object from 'save' method seems ok, since I get an always increasing ID value.
Suggestions?
Cheers
FB

check whether we are populating the data properly in your bean and check it before passing to save method of spring data jpa

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.

Spring Rest Controller - business validations & resolving id

We are designing rest api for our existing application using spring+jpa.
want to validate the input/request payload prior to persisting. Have found #PrePersist listener method and hope we can validate entity business validations(unique etc) and id's can be resolved in prior to persist, however had few issues
EntityManager is not auto wired: trying to autowire entity manager in super Entity class like below so that entityManger object can be used in all subclasses
#PersistenceContext
protected EntityManager entityManager;
Understood that since the entity is not spring managed bean, entity manager object is not autowired.
After setting entiy object manually (as a workaround for point 1), while trying to resolve ids based on user provided values in PrePersist callback method resulted is getting same method called recursively.
any suggestion/way to implement business validation and resolving ids based on values from jason payload for rest api would greatly appreciate.
Thanks
Have implemented AOP aspect to validate the rest resources prior to persisting which is working pretty good as expected.

Lazy loading works, but shouldn't

The context of this question is within spring-boot, using spring-data-jpa and hibernate.
A colleague wrote an #Service and annotated the service method with #Transactional. The service method loads an entity, and subsequently hits a one-to-many lazily loaded collection (fetch = FetchType.LAZY). The service method is invoked by some custom delegator, which i will come back to. This works fine when invoked from a #RestController endpoint.
When i invoked the service from a camel route (again via the custom delegator) it barfed with a lazy initialization exception.
On digging, found that the service implements an interface, the custom delegator looks up the service (it is injected so has proper proxy) and calls a method
on the interface which is actually a java-8 default method. This default-method then locally calls the #Transactional method.
So there's the problem :- this is a LOCAL method call so the aspecting/proxy-ing of the #Transactional annotation is not done (we use aspectJAutoProxy) so the method is NOT invoked within a transaction, so the lazy-loading SHOULD fail. And to double-check, also tried it via an #Scheduled annotation: same behaviour. Barfs like it should.
My Question: So why does it work when called from the #RestController? This is driving me nuts!
There is no transactional annotation on the rest controller endpoint.
I added some debug code to the service using TransactionSynchronizationManager.isActualTransactionActive() and it shows that in no case is there a transaction, even when being called via the controller endpoint.
So why does the lazy loading work when being called from the controller?
I dumped all SQL and at no points are the lazy-collection already loaded, so they are not in any hibernate cache.
I remember reading once that lazy loading was a hint, not a command, but still... why does it work in that one case?
after being perplexed by this on many occasions, have stumbled across the answer:
sprint-boot is doing an open-entity-manager-in-view behind our backs via the OpenEntityManagerInView interceptor. Had no idea this was going on.
See this excellent answer from Vlad Mihalcea https://stackoverflow.com/a/48222934/208687
When your method annotate to transactional hibernate session close after return method , if object that return from method have lazy , lazy property not load and you get exception that session close. You can use fetch in query or using OSIV

Why doesnt #Transactional and #RequestMapping work together?

The moment I include the #Transactional annotation on a #RequestMapping, I notice in springboot that the url mappings do not auto-configure.
What could be responsible for this?
I want a case where (C)R(UD) rest calls work within a transaction.
If you're goal is to ensure your CRUD operations happen within a transaction, then using Spring Data JPA, this is done for you by default. Creating a repository interface that extends CrudRepository for example, your query methods will inherently be #Transactional. You can customize the #Transactional attributes by manually annotating a query method on your repository, but this need only be done if you want non default behaviour.
See the Spring Data JPA docs for more details.
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

In-memory structure in Spring

I'm a Spring novice user.
I have a database table which is static in nature and contains only a few records.I want a Map-like structure(id - name) that holds two columns of this table. This Map must be loaded/initialized when the web application is started and must be applicable throughout the application's context, independent of the users sessions and must be read-only. This way, I can save a lot of DB queries as the different operations will simply read from this Map.
While I'm aware of ServletContextListener etc. of Java EE, I don't know how to achieve the same in Spring. Is a Spring Service bean the right place/way to initialize and store such a Map?
Please guide me about the same.
You can create a regular spring bean exposing a method which loads the data you require from the database and stores it in your map. Annotate this method with #PostConstruct and spring will ensure that it is called when your application context starts, hence loading your map.
You could use springs JdbcTemplate to load your data within this method
See Spring PostConstruct doco for information on the #PostConstruct annotation
See JdbcTemplate doco for information on JdbcTemplate
You can configure lists, sets and maps in a Spring XML configuration. See here for more examples.

Resources