I see with the Spring Boot you don't need to open and close the hibernate session.
But for the understanding purpose how it is working internally, On which layer it is opening the hibernate session and when it is closing.
I created one POC.
I have one Spring boot application it has two Entity One is Customer and other is Address and there is one to Many relation between Customer and Address.
And I have one two Apis one is adding record and other is fetching all the records.
These APis are there in the CustomerEndpoint and it is annotated with
#RestController
#RequestMapping(value="/customer").
And also created CustomerRepository which extends CrudRepository for saving and fetching the Customer records.
So as per my understanding while fetching the Customer using CustomerRepository inside CustomerEndpointclass should throw LazyInitialization error when we will say customer.getAddress(as its fetchtype is LAZY).
But it is not throwing any error, it is working properly.
I was thinking the hibernate session not be there in the CustomerEndpoint class.
Can anyone help me how this Hibernate session is maintained by Spring boot?
As everybody is thinking it as a duplicate of another question but my question is not top of their explanation as according to them session is valid till the Repository so according to that i should get LazyInitialization exception while saying customer.getAddress inside CustomerEndpoint as it is not a Repository but i am not getting any Exception
First of all it is not a good practice to use Repository layer in your Presentation layer.
OSIV (Open Session in View) is enabled by default in Spring Boot, and OSIV is really a bad idea from a performance and scalability perspective.
Because of this you are not getting the exception and able to work in your presentation layer.
Check by putting the follwoings in your application.properties file
spring.jpa.open-in-view=false
You can refer OSIV AntiPattern for more details
I think, It still works If your customer.getAddress is inside the transaction
Related
There's a straight-forward way of using redis, jdbc, etc as persistence for spring sessions with minimal configuration but due to some serialization issue which I have been facing in that approach, I am thinking of having a custom implementation to intercept the session and then write implementations for save and retrieval of the session in redis and spring security take care of everything else.
Currently, in my application (thymeleaf based frontend), I have integrated spring-security for a form-based authentication.
Just to mention, the issue I am facing and which is what I am trying to avoid, is that with the config based persistence approach, I am getting serialisation exceptions for the model classes which I am using in various views. I am not understanding why session layer is trying to persist other POJOs along with just the session. Tye solution was to have those POJOs implement Serializable but this was also required to be done for library classes as well.
I am new to Hibernate and Spring boot. I understand that hibernate is ORM tool so that you can map objects to database and just use save() to save obj into the database automatically. In Spring Boot, I would do something like
public interface CourseRepository extends CrudRepository<Course, String>{
}
and somehow I will get all the CRUD operations like save and findAll etc.
From another tutorial of hibernate, it says that session is required to save the object to the database. However, I don't see any form of sessionfactory or session being implemented in Spring boot and I am still able to do the save and findAll operations etc.
How is this happening and what relations does this have with hibernate?
Where exactly should I start to find out more about hibernate, stuff like #OneToMany and basically understand the details of the whole application to database operations in spring boot? Thanks
Spring Boot takes care of all the session management. Refer to this question for better understanding:
Spring Boot & Spring Data: how are Hibernate Sessions managed?
there are two things crudRepository and sessionFactory. try to find out difference between them and also try to read what is JPA and Hibernate.
I have a requirement where i need to configure a Spring based application to work with two databases. We have two databases, one that we use to keep the live data and the other database is used as a datawarehouse and contains archived data (which has the exact structure as the Live db).
To keep it simple, assume that there is a request to search for a product. What the application should do is to search for the product details in the Live database and if not found it will check the archive database.
If i need to configure such a setup, do i still need to configure to datasources and would the search code have to use the first datasource to check the live database and if not found it will run another query using the archive database?
The above is probably doable but i am wondering whether there is a better way of doing this. For example, is it possible for the application to work on a single datasource even though behind the scenes it actually works with two databases?
The application is based on Spring, JPA/Hibernate, SOAP and Mysql database and Jboss 7 as the application server.
Any examples showing how this is configured using Spring and Jboss would be very useful.
Thanks
Spring has exactly what you want - the AbstractRoutingDataSource. See this blog post on how to use it. In your case, you need to switch the datasource during one request, so you'll need to have 2 transactions, switching the datasource between them by changing the datasource indicator on the ThreadLocal:
For these DAOs, demarcate the wrapping Service-layer either with distinct packages, class names, or method names
Indicate to Spring that the Service-layer method calls should run in their own transactional contexts by annotating with #Transactional(propogation=Propogation.REQUIRES_NEW)
Create an Aspect (using AspectJ annotation #Aspect) to fire around the service-layer method calls (using #Around) to set the ThreadLocal value before the method call, and to unset it afterwards
In the #Controller, simply call the Service-layer methods. The Aspect will take care of setting the values to indicate which datasource to use, and the AbstractRoutingDataSource will use that datasource in the context of each transaction.
I've been looking at the code generated by Spring Roo and I noticed that the persist() method it creates is given Propagation.REQUIRES_NEW. Wouldn't the default propagation be sufficient?
#Transactional(propagation = Propagation.REQUIRES_NEW)
public void Entity.persist() {
if (this.entityManager == null) this.entityManager = entityManager();
this.entityManager.persist(this);
}
Some additional information. Here is the roo log that produced this code:
// Spring Roo 1.1.0.RELEASE [rev 793f2b0] log opened at 2011-02-04 10:01:02
project --topLevelPackage org.sotest.sscce --projectName Test --java 6
// Spring Roo 1.1.0.RELEASE [rev 793f2b0] log closed at 2011-02-04 10:01:04
// Spring Roo 1.1.0.RELEASE [rev 793f2b0] log opened at 2011-02-04 10:01:06
persistence setup --database GOOGLE_APP_ENGINE --provider DATANUCLEUS
entity --class ~.entities.Entity
exit
// Spring Roo 1.1.0.RELEASE [rev 793f2b0] log closed at 2011-02-04 10:02:55
I am using the GAE database with the DN provider. I simply created an entity, I did not touch any files other than issuing the above roo commands. When I open Entity_Roo_Entity.aj I get the above code.
I will try this again on the latest version of Roo and verify the same output. I will also post this issue on a Roo-related forum.
Update: The same code is generated with Roo 1.1.1 (latest version)
SECOND ANSWER (after additional info was added to question)
It's likely due to the use of GAE. The GAE datastore doesn't use traditional transaction semantics. See description of GAE's transaction isolation here. Specifically:
Queries and gets inside a transaction
are guaranteed to see a single,
consistent snapshot of the datastore
as of the beginning of the
transaction. ... This consistent
snapshot view also extends to reads
after writes inside transactions.
Unlike with most databases, queries
and gets inside a datastore
transaction do not see the results of
previous writes inside that
transaction. Specifically, if an
entity is modified or deleted within a
transaction, a query or get returns
the original version of the entity as
of the beginning of the transaction,
or nothing if the entity did not exist
then.
There are also restrictions on querying within a transaction. With this in mind, the REQUIRES_NEW is probably added so that any subsequent reads of the entity within the "first" transaction work as expected. Seems confusing and non-standard, but perhaps this is the best option when working in the constraints of GAE.
FIRST ANSWER
There must be a misunderstanding or something else at
play. I just checked with Roo v1.1.1
generating a simple entity with
Hibernate provider, and the default
transaction propagation is used. This
is also somewhat verified in the
documentation:
All persistence methods are configured
with Spring's Transaction support
(Propagation.REQUIRED,
Isolation.DEFAULT).
Using Propagation.REQUIRES_NEW would
not make sense for the default persist
methods.
I'm not an expert in Roo, so can't
even think of anything that might do
this. Perhaps you should post more of
your code, particularly any
non-standard configurations. Random
questions/ideas:
Are you using Hibernate provider or ?
Any custom configuration of the persisence-unit?
Do see the Propagation.REQUIRES_NEW on all of
your entity persist methods?
Where are you seeing the propagation annotation. (e.g. In the
*_Entity.aj file?)
Is there any chance that your entity class (or one of it's parents)
has it's own .persist method (thus
overriding Roo's generated method).
1:
http://static.springsource.org/spring-roo/reference/html/base-persistence.html
1: ah. I think it's highly likely to be due to use of the GAE/DN provider. I'll modify my answer accordingly. In the meantime, check out the notes around GAE's transaction isolation here: http://code.google.com/appengine/docs/java/datastore/transactions.html .
I am using Turbine 2.3.2 with Hibernate 3. My problem is that the Hibernate session is not active when my (Velocity 1.6.4) template is executed, and I am accessing data from the database for which Hibernate needs lazy initialization. Therefore I get a LazyInitializationException - no Session error.
Since I want my Hibernate session to be alive when a velocity template executes I would like to have a class to execute after and before the Velocity template. This way I could open and close my Hibernate session at one place. (Disabling lazy initialization in Hibernate is not an option for me). Are there any possibilities related or not to Turbine to write a kind of listener or a filter (I am not sure how to call it) that would execute right before and after a Velocity template has been executed? Or maybe the servlet container could filter requests .... What option would you recommend?
Try looking at the Spring OpenSessionInViewFilter. It opens the Hibernate Session and assigns it to a threadlocal. That way, you can pick it up in your data access layer and use it.
Open Session in View is not a clean solution. You can configure in your criteria (if you use it) which association paths Hibernate has to eagerly fetch.
If you use HQL, just "touch" the association while the session is still open.
Your question seems to be about the (in)famous Open Session In View (OSIV) pattern.
Have a look at the Open Session in View page on the JBoss wiki, you'll find a filter based implementation (non Spring based).