lazy loading in granite ds - graniteds

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.

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.

Can I prevent a LINQ DataContext from using a transaction when a TransactionScope is present?

I'm using a TransactionScope in a model controller class that coordinates several lower level, data access classes. The data access classes each use their own LINQ DataContext, and thanks to the magic of TransactionScope, they all participate in the same transaction if one is present.
Under normal circumstances, this is perfect and everything works. However, I've added an activity logging class and one of the places it can write to is the database. Unfortunately, it automatically picks up on the TransactionScope and if the transaction gets rolled back, so do all the log entries.
I've checked the Transaction property of the DataContext and it's null, as expected, so I'm not sure how to tell it to ignore the TransactionScope.
In your logging class, wrap your using(new datacontext()) into:
using (var s = new TransactionScope(TransactionScopeOption.Suppress)) {
}

Spring OpenentityManagerInViewFilter alternative

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

How to handle a large set of data using Spring Data Repositories?

I have a large table that I'd like to access via a Spring Data Repository.
Currently, I'm trying to extend the PagingAndSortingRepository interface but it seems I can only define methods that return lists, eg.:
public interface MyRepository extends
PagingAndSortingRepository<MyEntity, Integer>
{
#Query(value="SELECT * ...")
List<MyEntity> myQuery(Pageable p);
}
On the other hand, the findAll() method that comes with PagingAndSortingRepository returns an Iterable (and I suppose that the data is not loaded into memory).
Is it possible to define custom queries that also return Iterable and/or don't load all the data into memory at once?
Are there any alternatives for handling large tables?
We have the classical consulting answer here: it depends. As the implementation of the method is store specific, we depend on the underlying store API. In case of JPA there's no chance to provide streaming access as ….getResultList() returns a List. Hence we also expose the List to the client as especially JPA developers might be used to working with lists. So for JPA the only option is using the pagination API.
For a store like Neo4j we support the streaming access as the repositories return Iterable on CRUD methods as well as on the execution of finder methods.
The implementation of findAll() simply loads the entire list of all entities into memory. Its Iterable return type doesn't imply that it implements some sort of database level cursor handling.
On the other hand your custom myQuery(Pageable) method will only load one page worth of entities, because the generated implementation honours its Pageable parameter. You can declare its return type either as Page or List. In the latter case you still receive the same (restricted) number of entities, but not the metadata that a Page would additionally carry.
So you basically did the right thing to avoid loading all entities into memory in your custom query.
Please review the related documentation here.
I think what you are looking for is Spring Data JPA Stream. It brings a significant performance boost to data fetching particularly in databases with millions of record. In your case you have several options which you can consider
Pull all data once in memory
Use pagination and read pages each time
Use something like Apache Spark
Streaming data using Spring Data JPA
In order to make Spring Data JPA Stream to work, we need to modify our MyRepository to return Stream<MyEntity> like this:
public interface MyRepository extends PagingAndSortingRepository<MyEntity, Integer> {
#QueryHints(value = {
#QueryHint(name = HINT_CACHEABLE, value = "false"),
#QueryHint(name = READ_ONLY, value = "true")
})
#Query(value="SELECT * ...")
Stream<MyEntity> myQuery();
}
In this example, we disable second level caching and hint Hibernate that the entities will be read only. If your requirement is different, make sure to change those settings accordingly for your requirements.

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.

Resources