• Post Reply Bookmark Topic Watch Topic
  • New Topic

Deciding on what method to use to avoid LazyInitializationExceptions

 
Randy Maddocks
Ranch Hand
Posts: 92
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everyone, I am looking for the best solution to avoid a LazyInitiallizationException.

To summarize my situation: I am developing a web app that retrieves and writes values from and to one of several primefaces (3.5) forms to a couple of tables in a database (Oracle 11). The app is being developed in NetBeans 8, and runs on a JBoss EAP 6.21 server, with java 1.7.0_71 jdk. I am using native SQL query format with createNativeQuery. There is a @OneToMany collection in the "parent" Entity that accesses objects in the Entity "child" class. I have left it using the default LAZY fetching method. The collection object will need to be accessible in order to populate certain fields on an editable primefaces form when a user clicks an Edit button on another primefaces form containing values in a datatable that were retrieved from the database using the aforementioned native SQL query. The database is not large (i.e. it will likely never have millions or even hundreds of thousands of records), but performance is obviously something I do not want to negatively impact by using the wrong, or rather, least efficient method.

I have researched online and have found the following 4 methods that I know of:

1. Using the EAGER fetch method. What I like about this is I am leveraging the power of annotations, seems so uncomplicated. But, what will the performance impact be if the collection grows significantly?
2. Load the collection by Session Open using a ConnectionFilter. Although, to my understanding, no editing of model classes is required, what impact does having a database connection constantly open during a session impose on the performance of the app? And maybe there are other risks or disadvantages I am not aware of.
3. Load the collection by Stateful EJB with PersistenceContextType.EXTENDED. I understand this only works for JEE (which is fine, that is our environment). There is the risk of a N + 1 effect happening, as well as increased EJB overhead that could negatively impact container memory. Also, I am using @Stateless sessions, what would affect be changing to @Stateful sessions?
4. Load collection by SQL JOIN. I know conceptually this method seems simple to understand, but to be honest, I tried JPQL using @NamedQuery with JOIN in my queries but got frustrated trying to retrieve values from the collection, that's why I ended up using native SQL queries and createNativeQuery.

I am relatively new to EJB, so some of the concepts I am still desperately trying to bring myself up to speed on. If anyone can shed some light on this for me it would be greatly appreciated.

I have to close on a note of praise for coderanch. This is an excellent site, by far! I have found so many answers and learned so much from having gone through the forums and articles over the years. The time and effort all the experts put into helping people like myself is appreciated more than you ever know. Just to have some concept that is confusing suddenly become clear is fantastic. So a huge thanks to the contributors!
 
Arun Kumarr
Ranch Hand
Posts: 662
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Assuming all your design is around the entity model -- > parent, child(ren), referential etc., you may want to consider this approach.

1. Load only the parent object (id first) and if need be load the entire parent object.
2. Load the child(ren) (again id first and the entire child object, as per need). When you are loading the child, make sure that you lazily load the children information in a particular batch ( 50 at a time). If needed go fetch the next 50 and so on. But hey, wait don't keep loading the children until the end of records. Have an overall count, if needed. If possible get the count of children before hand so that it is easy to arrive at the total set of runs you may need to run.
Also once you have taken the child and given it to the next layer(say a typical web application), you can choose to cache it in some place (on the HTML screen, json object ??) and you can go ahead and clear the children list or set and fetch the next set of records.
3. Add cache to the fetches (with a timer beyond which it expires and values are cleared). By this you don't eat up lot of memory as it clears itself every now and then. (You may want to consider having clearing policies for the cache like Least recently used, Least Linked/referred Object).

If someone wants to load the entire children, the you may want to look at the use case and have a dedicated efficient and fast eager fetch (preferaly nativeSQL).
 
Randy Maddocks
Ranch Hand
Posts: 92
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Arun, thank you very much for your reply. I will try the approach you suggest. Thank you once again!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!