Spring OpenentityManagerInViewFilter alternative - spring

Beacause of the issues mentioned in :
Why not to use Spring's OpenEntityManagerInViewFilter
and
http://heapdump.wordpress.com/2010/04/04/should-i-use-open-session-in-view/
I'd like to use an alternative for Springs OpenentityManagerInViewFilter. This is definitely a performance issue. If I disable the OpenentityManagerInViewFilter I ocassionally get the error:
LazyInitializationException:42 - failed to lazily initialize a collection

One alternative to the filter is to access all of elements in a collection that is lazy loaded before sending them via the request to the view. However, at this point you should question whether these attributes need to be eagerly fetched.
Here is some psuedo code to demonstrate.
//Inside controller
Department dept = dao.findDepartment(id);
//This will load the entities, avoiding the exception.
for(Employee e: dept.getEmployees()){ //Assume employees are lazy loaded
e.getName();
}
request.setAttribute("department", dept); //In Spring this could be the model

Related

lazy loading with Spring data

I'm using Spring data which is easy to use but i can't control it because i got error there
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: entity.Qualite.fonctions, could not initialize proxy - no Session
I know FetchType.EAGER will work but i want keep it lazy.
so how can i control the session in spring data
#RequestMapping(value="/loadfonction")
public #ResponseBody
Set<Fonction> loadfonction(Map<String, Object> model, HttpServletRequest request) {
Set<Fonction> fonctions = qualiteRepo.findOne(Integer.valueOf(request.getParameter("idquality"))).getFonctions();
System.out.println(fonctions.size());
return fonctions;
}
I even try #Transactional annotation but it didn't work:
#Transactional
#RequestMapping(value="/loadfonction")
This is a common problem with trying to open a view using the spring mvc framework. The control method closes the session before the view can display it. (Trying to keep the view out of the business logic) To get around it you can use the OpenSessionInViewFilter class.
Here is an article on how to implement it:
http://blog.cloudmate.pl/2010/09/hibernates-open-session-in-view-in.html
In your repository you cannot use query methods to initialize the collection. Instead you should define a query like that to fetch the collection with it. Change your query according to your domain, I can't really figure out how it should look for you.
#Query("SELECT q FROM Qualite q JOIN FETCH q.role WHERE q.fonctionId = (:fonctionId)")
public Qualite findById(#Param("fonctionId") String fonctionId);
You can't. The only way to avoid this problem is to do a query when you want to retrieve the Fonction objects.

Lazy initialization exception in TestNG unit testcase to test Spring service layer

I am getting the lazy initialization exception while testing the spring service layer with TestNG testcases. Could you please help me out to resolve the issue. Not sure if I'm missing any thing in the below testcase. But if I create and execute the testcase for same method in Dao layer then its working fine.
You have the following mapping
<set name="validResponses" lazy="true" inverse="true"
which lazily loads the InspectionQuestion.validResponses field.
I'm going to assume that
InspectionQuestion iq = inspectionStepQuestionService.getActiveInspectionQuestionByCode(QuestionType.COUNTRY_ORIGIN);
is done within a Session and a Transaction. When the method returns, the Transaction is committed and the Session is closed. As such, any fields that are not eagerly loaded are in an un-initialized stated. Trying to initialize them after this will cause the LazyInitializationException that you are seeing.
The simple solution would be to change lazy="true" to lazy="false", but this may not be what you want always.
Instead, maybe change your InspectionStepQuestionService methods to fully initialize your entities when required
Hibernate.initialize(inspectionQuestion /* or entity to return */);
By adding the below annotation in the test class, I'm able to maintain the session. #TransactionConfiguration(transactionManager="hibernateTransactionManager", defaultRollback=true).

struts2 spring jpa layers best practice

I have an app written with Struts2 Spring3 JPA2 and hibernate. In this app i have the following levels :
- struts2 actions
- spring services
- spring DAO
So, one struts action call for a service which can contain calls to one or many dao objects.
In order to display the info on the screen i have created some "mirror" objects for entities; ie: EmailMessage entity has a EmailMessageForm bean that is used to display/gather data from webforms (i don`t know if this is the best practice), and hence my problem.
In EmailMessageServiceImpl i have a method called:
public List < EmailMessage > getEmailMessages(){
//code here
}
and, if i call this from struts action i cannot get dependencies because session has expired (i have TRANSACTION entity manager). So, one solution would be to create another method
List<EmailMessageForm> getEmailMessagesForDisplay()
{
//....
}
and here to call for getEmailMessages() and convert this to form objects.
What do you recommend me ?
What is the best practice for this kind of problem ?
If by "dependencies" you mean "lazy-loaded objects", IMO it's best to get all the required data before hitting the view layer. In your current architecture it looks like that would mean a service method that retrieves the DTOs ("form beans"; I hesitate to use the term since it's easy to confuse with Struts 1).
Some say using an Open Session in View filter/interceptor is better. It's easier, but can lead to unintended consequences if the view developer isn't paying attention, including multiple N+1 queries etc.

Hibernate bidirectional query

I have a question regarding Hibernate bidirectional. Lets say I have 2 classes, Class A and Class B and bidirectionally related. That means when I query Class A, I also can get Class B and vice versa. My question is how hibernate work when I do this
ClassA classA = ClassA.findClassAById(1);
ClassB = classA.getClassB().getClassA().getClassB();
I know I can get ClassB with just classA.getClassB();, but I also can get classA.getClassB().getClassA().getClassB().getClassA().getClassB()...;
Can someone explain to me how hibernate work with bidirectional query?
I'm concerned about performance.
Hibernate employes an efficient first level cache also known as the PersistantContext
If an object is loaded in the context , hibernate does not hit the database to get the same object.
In the problem statement when findClassAById(1) is called classA object is loaded in the persistance context. classB object is loaded at the same time or later depending on the lazy loading/eager loading strategy adopted. Following which the database should not be hit ideally for all future calls.
You can very well google Persistance Context for more information about how it works.

lazy loading in granite ds

how will i load my entities in my flex application using lazy loading .I have a deep object graph
GraniteDS, together with its data management framework, lets you transparently load your uninitiated associations: see documentation here. So, basically, you don't have to do anything special in order to initialize your lazy collections/proxies, you only need to access one of them on the client side (asking for the size of a collection for example) and it will trigger a call to the server and fetch the uninitialized data.
If you don't want or can't use transparent lazy-loading, you need to write a specific initialization method which must have access to an EntityManager, receive your entity as a parameter, initialize the required association and send the entity back to the client.
AFAIK it's impossible. You should have opened hibernate session to do this.
In my project I'm doing what you need this way:
I have spring service like this:
public interface SomeObjectManager {
List<SomeObject> getObjects(); // here we have lazy loading for SomeObject's properties
SomeObject getFullObject(long objectId); // here we're loading full object
}
Some properties of SomeObject use lazy loading. To load them I use HQL query like this:
SELECT s FROM SomeObject s
LEFT JOIN FETCH s.child children
LEFT JOIN FETCH children.items items
LEFT JOIN FETCH items.property
WHERE s.id=:id
This query forces hibernate to load properties defined lazy.
So if you don't need fully loaded SomeObject instances you use getObjects() method. If then you need details on concrete SomeObject instance you use getFullObject() method.
Hope this helps.

Resources