Hibernate Lazyloading in OOP-style - java

So, lets imagine that I have two objects: Course and Exercise. Course Contains list of Exercises.
Lazy loading is enabled, and via Repository I get a Course that I'm interested in:
couserRepo.query(new ByNameSpec("courseName")).
Now I want to acces Course exercises, but when I call course.getExerccises() I get a msg, that session is closed already.
So, I have to make another query to repo, that is absolutely not convinient.
What to do with this?

Remember that opening session per operation is antipattern. See http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#session-per-operation for more information.
The scope of a Hibernate org.hibernate.Session is flexible but you should never design your application to use a new Hibernate org.hibernate.Session for every database operation.
I think you should consider Session-per-request pattern.

Related

Hibernate - lazy load and update single object from the db

I was lately working on optimizing my application performance, and I noticed that when I lazy load a dependency with MazyToOne relationship, object that hibernate provides is not just lazy loads the object itself, but also all of its fields - so, it has made me think if I maybe can use this to my advantage
Let's imagine the situation like this
#Transactional
public void updateUserNameToHarry(Long userId){
User u = dao.findById(userId);
u.setName("Harry");
}
So we have opened a transaction, loaded Harry into our persistence context, and updated his name.
Once the transaction is closed Hibernate will do its magic and update the name of the user entity we have.
But, in this scenario, I don`t really need to parse Harry db row into entity graph, load Harry into application context, and I definitely do not need to do all of this for the eagerly loaded relationships of Harry.
So here is the question - can I avoid this somehow?
Ideally, I would like Harry to be a lazy loaded object that upon calling setName method adds a single update query, that is going to be executed once the transaction commits.
I am currently using Spring boot 2.0 stack, but my question applies to any other versions and approaches to ORM with java.
If I understand correctly, these options came to my mind:
1 - obvious one - don't load User at all, just perform update query yourself (UPDATE user SET name = 'Harry' WHERE id = :userId) - number of ways to achieve this, named query, spring method with annotation etc.
2 - there is a getReference method in EntityManager, it allows you to get User proxy with only it's ID filled, unless you perform some actions on it, then the fields are loaded. It's not gonna help with such as simple case as you posted, but if your User had relations to other entities, then you could benefit from it - have a look at this, it's a perfect explanation

Simplest way of using Hibernate Sessions

I'm coaching a student project which uses hibernate as a persistence layer. From my projects at work I'm already quite familiar with hibernate and can use it with few 'troubles'. But with this project we have constantly problem with sessions, stale objects and and 'object was loaded from a different session'-errors.
So what I am looking for the simplest possible way to use sessions:
Ideal would be:
Sessions can be fetched from anywhere
It shouldn't matter whether or not a given object was loaded with session A and then updated with Session B
Its a single-process GUI application. The current setting for current_session_context_class is thread. But I use a static field for the session variable (which I think causes some of my troubles) and only fetch it ONCE.
Thanks for your assistance!
Cheers,
Reto
Assuming you're not teaching ORM, the understanding of why these errors happen isn't part of the knowledge the students are supposed to come away with etc etc etc and you just want Hibernate to work as a database wrapper so they can get data to use while learning other things.
This is probably your best bet:
StatelessSession session = sessionFactory.openStatelessSession();
A stateless session is effectively "auto-commit mode for ORM" and as close to raw-JDBC wrapper as hibernate gets. No Sessions, no L1 caches, no persistence context. Just SQL/HQL that returns objects.

A typical lifecycle of a Hibernate object in a web app -?

Describe please a typical lifecycle of a Hibernate object (that maps to a db table) in a web app.
Suppose, you create a new instance of an object and persist in the db.
But during the app lifetime you'll be working on a detached object and finally
you need to update it in the database, for example on exit.
How does it look like with hibernate and spring?
p.s. Can transactions and sessions live between servlet transitions? So that we opened 1 session and use it in all servlets without a need to reopen it?
I'll try to give a descriptive example.
Suppose, when the app starts, the log record is created. this can be done at once,
Log log = new Log(...) and then something like save(log) -- log corresponds to a table LOG.
then, as the application processes user inputs and keeps going, new data is being accumulated.
and after the second step we could add something to a log object, a collection for example:
// now we have a tracking of what user chosen: Set thisUserChoice,
// so we can update the persistent object, we have new data now !
// log.userChoices = thisUserChoice.
Here occurs the nature of my question. How are we supposed to deal with it, if we want to
update the database whenever new data is gotten from a user?
In a relational model we can work with a row id, so we could get this record and update some other data of the row.
In Hibernate we are also able to load a object by its id.
But is IT THE WAY TO GO? IS ANYTHING BETTER?
You could do everything in a single session. But that's like doing everything in a single class. It could make sense from a beginner's point of view, but nobody does it like that in practice.
In a web app, you can normally expect to have several threads running at once, each dealing with a different user. Each thread would typically have a separate session, and the session would only have managed instances of the objects that were actually needed by that user. It's not that you can completely ignore concurrency in your own code, but it's useful to have hibernate's help. If you were to do everything with one session, you would have to do all the concurrency management yourself.
Hibernate can also manage the concurrency if you have multiple application servers talking to a single database. The separate JVMs can't possibly share the same session in this case...
The lifecycle is described in the hibernate documentation (which I'm sure you've seen).
Whenever a request comes from the web client to the server, the first thing you should do is load the relevant objects (see section 10.3) so that you have persistent, not detached entities to deal with. Then, you do whatever operations are required. When the session closes (ie. when the server returns the response to the client), it will write any updates to the database. Or, if your operation involves creating new entities, you'll have to create transient ones (with new) and then call persist() or save() (see section 10.2). That will result in a managed entity -- you can make more changes to it, and hibernate will record those changes when the session closes.
I try to avoid using detached objects. But if I have to (perhaps they're stored in the user's session), then whenever they might need to be saved to the database, you'll have to use update() (see section 10.6). This converts it into a managed object, and so the session will save any changes to the database when it's closed.
Spring makes it very easy to generate a new session for each request. You would normally tell Spring to create a sessionFactory, and then every request will be given its own session. Search for "spring hibernate tutorial" and you'll find several examples.
http://scbcd.blogspot.com/2007/01/hibernate-persistence-lifecycle.html This explains transient, persistent objects.
Also have a look at the Lifecycle interface to know what hibernate does (and it provides hooks at all stages for user to do something)

How to implement database functionality effectively?

I am developing a Java Desktop Application which uses MySQL database. The DB has 6 tables. Every table, as usual, should allow CRUD (Create, Read, Update and Delete) operations.
I have designed 6*4 = 24 JPanels, 4 JPanels for each tables. Each JPanel have Components to take user input and perform the CRUD operation for which it is designed. For instance, a JPanel3 is designed for Create operation for Table1.
Now I want to know the following:
Q1. Would it be better to write 24 functions, each performing a specific function for a specific table?
Q2. This kind of situation is very normal as every application generally has many tables. So, Are all those applications use this approach of writing each function for each operation for each table?
Q3. As it is a Swing Application and every CRUD operation need the database connection, so Would it be better to make a connection to the database when the user starts the application?
or
Would it be better to make the database connection at the time when user clicks on the "save" or "edit" or "delete" or "create" button?
Q4. Would it be better to refer the connection from an instance variable which is shared by all the 24 functions? or Would it be better to have every function its own Connection?
Any other suggestions are also welcomed.
See this article about the DAO pattern, and then
see the Don't repeat the DAO! article so that you make a generic, reusable DAO.
In short - wrap your database access functionality in a single class and reuse that class from everywhere, thus effectively making your application not explicitly dependent on database operations - only on the DAO class (interface).
A1. No. The design should be guided by the requirements and the domain logic, not by technical considerations. Usually, it does not make sense to have all CRUD operations separately accessible to the user for each and every table. Write functions to perform those operations together that belong together.
A2. No. Nowadays, most applications use an Object/Relational mapper like Hibernate for this kind of thing. But still, there should be application logic on top that executes related operations together.
A3/4. Use a DB connection pool. O/R mappers generally do that automatically.
It would be great if you could join a project with experienced people. Your questions are understandable but... most project already have solutions for this.
I believe there are many more problems than the ones you describe, and you could work for months just to discover the questions ;-)
There are so many suggestions you might need that we can't even start.
Could you consider a framework such as Hibernate?
Although it would be complex for you to learn, in the process (and the recommandations) you would learn a lot about the database layer problems and solutions.
But to answer some of your questions :
Q1 : no, writing 24 functions would be a lot of duplication.
Q2 : certainly not.
Q3 : A database connection typically times out. I suggest to ask for one at appropriate times..., for example in the cases you describe.
Q4 : obtaining a connection should be shared code.
Q1: Could you have fewer JPanels and use a JComboBox to let the user pick wich table to operate on? That will probably save you some code.
Q2: In some way, yes. But see my answer for Q4.
Q3: Do the connection when the user clicks, and leave it open as short time as you need. Database connections takes resources.
Q4: It would be much better if you do all the Database-code and interacting in a single class, called Data Access Object, then is it much easier to change database from MySQL if you would like. See http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javadb/
What does the application do?
I hope you're using more descriptive names for your objects than "JPanel3" and "Table1"?
It would be better if you write no code.
Yes! Just drag and drop.
Data validation, reports and graphs.
Create a complete database program without writing a single line of code.
Common things such as new/edit/delete/search/update.
Use JDeveloper.

Open Session In View Pattern

I'm asking this question given my chosen development frameworks of JPA (Hibernate implementation of), Spring, and <insert MVC framework here - Struts 1, Struts 2, Spring MVC, Stripes...>.
I've been thinking a bit about relationships in my entity layer - for example I have an order entity that has many order lines. I've set up my app so that it eagerly loads the order lines for every order. Do you think this is a lazy way to get around the lazy initialization problems that I would come across if I was to set the fetch strategy to false?
The way I see it, I have the following alternatives when retrieving entities and their associations:
Use the Open Session In View pattern to create the session on each request and commit the transaction before returning the response.
Implement a DTO (Data Transfer Object) layer such that every DAO query I execute returns the correctly initialized DTO for my purposes. I don't really like this option much because in my experience I've found that it creates a lot of boilerplate copying code and becomes messy to maintain.
Don't map any associations in JPA so that every query I execute returns only the entities I'm interested in - this will probably require me to have DTOs anyway and will be a pain to maintain and I think defeats the purpose of having an ORM in the first place.
Eagerly fetch all (or most associations) - in the example above, always fetch all order lines when I retrieve an order.
So my question is, when and under what circumstances would you use which of these options? Do you always stick with one way of doing it?
I would ask a colleague but I think that if I even mentioned the term 'Open Session in View' I would be greeted with blank stares :( What I'm really looking for here is some advice from a senior or very experienced developer.
Thanks guys!
Open Session in View has some problems.
For example, if the transaction fails, you might know it too late at commit time, once you are nearly done rendering your page (possibly the response already commited, so you can't change the page !) ... If you had know that error before, you would have followed a different flow and ended up rendering a different page...
Other example, reading data on-demand might turn to many "N+1 select" problems, that kill your performance.
Many projects use the following path:
Maintain transactions at the business layer ; load at that point everything you are supposed to need.
Presentation layer runs the risk of LazyExceptions : each is considered a programming error, caught during tests, and corrected by loading more data in the business layer (you have the opportunity to do it efficiently, avoiding "N+1 select" problems).
To avoid creating extra classes for DTOs, you can load the data inside the entity objects themselves. This is the whole point of the POJO approach (uses by modern data-access layers, and even integration technologies like Spring).
I've successfully solved all my lazy initialization problems with Open Session In View -pattern (ie. the Spring implementation). The technologies I used were the exact same as you have.
Using this pattern allows me to fully map the entity relationships and not worry about fetching child entities in the dao. Mostly. In 90% of the cases the pattern solves the lazy initialization needs in the view. In some cases you'll have to "manually" initialize relationships. These cases were rare and always involved very very complex mappings in my case.
When using Open Entity Manager In View pattern it's important to define the entity relationships and especially propagation and transactional settings correctly. If these are not configured properly, there will be errors related to closed sessions when some entity is lazily initialized in the view and it fails due to the session having been closed already.
I definately would go with option 1. Option 2 might be needed sometimes, but I see absolutely no reason to use option 3. Option 4 is also a no no. Eagerly fetching everything kills the performance of any view that needs to list just a few properties of some parent entities (orders in tis case).
N+1 Selects
During development there will be N+1 selects as a result of initializing some relationships in the view. But this is not a reason to discard the pattern. Just fix these problems as they arise and before delivering the code to production. It's as easy to fix these problems with OEMIV pattern as it's with any other pattern: add the proper dao or service methods, fix the controller to call a different finder method, maybe add a view to the database etc.
I have successfully used the Open-Session-in-View pattern on a project. However, I recently read in "Spring In Practice" of an interesting potential problem with non-repeatable reads if you manage your transactions at a lower layer while keeping the Hibernate session open in the view layer.
We managed most of our transactions in the service layer, but kept the hibernate session open in the view layer. This meant that lazy reads in the view were resulting in separate read transactions.
We managed our transactions in our service layer to minimize transaction duration. For instance, some of our service calls resulted in both a database transaction and a web service call to an external service. We did not want our transaction to be open while waiting for a web service call to respond.
As our system never went into production, I am not sure if there were any real problems with it, but I suspect that there was the potential for the view to attempt to lazily load an object that has been deleted by someone else.
There are some benefits of DTO approach though. You have to think beforehand what information you need. In some cases this will prevent you from generating n+1 select statements. It helps also to see where to use eager fetching and/or optimized views.
I'll also throw my weight behind the Open-Session-in-View pattern, having been in the exact same boat before.
I work with Stripes without spring, and have created a manual filter before that tends to work well. Coding transaction logic on the backend turns messy really quick as you've mentioned. Eagerly fetching everything becomes TERRIBLE as you map more and more objects to each other.
One thing I want to add that you may not have come across is Stripersist and Stripernate - Stripersist being the more JPA flavor - auto-hydration filters that take a lot of the work off your shoulders.
With Stripersist you can say things like /appContextRoot/actions/view/3 and it will auto-hydrate the JPA Entity on the ActionBean with id of 3 before the event is executed.
Stripersist is in the stripes-stuff package on sourceforge. I now use this for all new projects, as it's clean and easily supports multiple datasources if necessary.
Does the Order and Order Lines compose a high volume of data? Do they take part in online processes where real-time response is required? If so, you might consider not using eager fetching - it does make a huge diference in performance. If the amount of data is small, there is no problem in eager fetching.
About using DTOs, it might be a viable implementation.
If your business layer is used internally by your own application (i.e a small web app and its business logic) it'd probably be best to use your own entities in your view with open session in view pattern since it's simpler.
If your entities are used by many applications (i.e a backend application providing a service in your corporation) it'd be interesting to use DTOs since you would not expose your model to your clients. Exposing it could mean you would have a harder time refactoring your model since it could mean breaking contracts with your clients. A DTO would make that easier since you have another layer of
abstraction. This can be a bit strange since EJB3 would theorically eliminate the need of DTOs.

Categories