jpa on a Desktop SWING Application
Asked Answered
D

4

5

I'm developping a mono user desktop application using SWING. I had a little experience with this kind of application on which i used the java.sql api and figured out that it wasn't confortable at all ...

In my new application i'm trying to use JPA for the first time, i've read a lot of tutorials which made me understand almost all what i need, but didn't find a good example for real java Desktop applications.

I'm thinking of using the following architecture, but don't know if i'm right ...

i think of creating a MyPersistenceUnit class :

    public class MyPersistenceUnit {
        private static EntityManagerFactory factory;
        private static EntityManager entityManager;

        public static void initiate(){
            factory=Persistence.createEntityManagerFactory("PU_Name");
            entityManager=factory.createEntityManager();
        }

        public static EntityManager getEntityManager() {
            return entityManager;
        }

        public static void close(){
            entityManager.close();
            factory.close();
        }

    }

the initiate() method will be the first to be called, and the close() method will be called when the application gets closed.

While the application is running all transactions will be done through the getEntityManager() instance, which is accessible every where in the application. If my understanding is right on JSE applications the obtained entity manager has an extended persistence context which will keep all the entities on the managed state while the entity manager doesn't get closed, and that's what made me think this way ...

I don't know if i'm missing something, so any tip will be appreciated

Note that i'm using eclipselink provider with the derby embedded database.
Thanks

Darr answered 20/9, 2011 at 21:5 Comment(2)
I don't see that this question has anything to do with Swing.Michaella
sorry for that, i've removed the tagDarr
D
2

After re-thinking my design, i decided to change it as follows:

  • create a 'permanent' EM when the application starts, and keep it open until the application shutdowns. permanentEM will be used to find/refresh entities when needed (for fetching lazy relationships for example ...).
    In order to ensure an efficient management of memory by the WEAK refrence-mode, i'll avoid to permanently reference permanentEM's managed entities.
  • create a 'temporary' EM to load the 'permanent' data, that are necessary for the start of the application. Once the data loaded close that temporary EM, to detach all the loaded-in-memory data.
  • create a new 'temporary' EM, for each persist/merge/remove transaction, and close it once the transaction commits.
Darr answered 9/11, 2011 at 13:41 Comment(1)
just a note: I've been using Eclipselink heavily for a year on a production system using a very similar design. While the application is actually an EE framework I've had to jump through a variety of application servers and I manage transactions on my own. Eclipselink does a very good job of not timing out, caching and "just working". If you have a client-server relationship to the data what you've suggested will work well (the cache might not reflect the state of the DB). If you're not using that you may see a small performance gain by caching. Good luck.Moldy
N
6

As I understand, the question boils down to whether you should open EntityManager and store its reference globally and access the same instance everywhere in the application.

I think that should be okay if your application is small to medium size. Just be cautious that database connection (hence session/entityManager) may drop due to various factors. And don't do this with transactions (ie dont open them in beginning and commit in end). Keep transactions as fine grained as possible.

There have been various discussion where more experienced people discussed about it, you can follow that here : for and counter argument on this SO question - Session management using Hibernate in a Swing application

Also see this on the same topic.

Here is a sample desktop application created by a committer of hibernate. Its bit old, you can get the idea.

And finally this is great article for understanding of general JPA concepts for desktop application.

Nauru answered 21/9, 2011 at 1:3 Comment(4)
I think i'll go with the counter argument, since i'm judging my application as a little bit bigger than medium. Now the problem is that i'm familiar with EclipseLink, and even tests i've checked in here shows that EclipseLink is better, unfortunately all the articles solving the problem are talking about Hibernate. Concerning the last link you gave, it just shows some very basic examples so it doesn't really solve my problem.Darr
I am glad you could make choice based on those links. If you ask for my personal opinion, I would always say don't keep the session/EM open for long, always open it only when needed. regarding Eclipselink, I have never used it myself on any real-life project so i am not in a position to comment on that, but i hope things wont be radically different conceptually.Nauru
At the end, i decided to use the long life persistence-context but with 'eclipselink.persistence-context.reference-mode' property set to 'WEAK' which will take in charge any memory management issues. I also set <shared-cache-mode> element to 'NONE', which will disable 2nd Level caching which is useless in my case, and use only L1 cache (related to the EM). I think this is the most logical solution, since creating a new EntityManager for each trasaction may be expensive. Thank you very much for the help @kunal.Darr
@GeorgeCasttrey am glad my response helped. And thanks for posting how you solved it. It will certainly help people searching on the same topic in future.Nauru
D
2

After re-thinking my design, i decided to change it as follows:

  • create a 'permanent' EM when the application starts, and keep it open until the application shutdowns. permanentEM will be used to find/refresh entities when needed (for fetching lazy relationships for example ...).
    In order to ensure an efficient management of memory by the WEAK refrence-mode, i'll avoid to permanently reference permanentEM's managed entities.
  • create a 'temporary' EM to load the 'permanent' data, that are necessary for the start of the application. Once the data loaded close that temporary EM, to detach all the loaded-in-memory data.
  • create a new 'temporary' EM, for each persist/merge/remove transaction, and close it once the transaction commits.
Darr answered 9/11, 2011 at 13:41 Comment(1)
just a note: I've been using Eclipselink heavily for a year on a production system using a very similar design. While the application is actually an EE framework I've had to jump through a variety of application servers and I manage transactions on my own. Eclipselink does a very good job of not timing out, caching and "just working". If you have a client-server relationship to the data what you've suggested will work well (the cache might not reflect the state of the DB). If you're not using that you may see a small performance gain by caching. Good luck.Moldy
H
0

Since its a SE application, your may use the embedded database. I know H2 normally allow one thread visit, so if your are in the same developing environment and want to avoid the headache concurrence control of entity.

my suggestion is that encapsulate the your service call in one thread and assign this thread a entitymanager.

don't allow other threads to use entities , then define data access interface which can transfer data from entity to other objects in a proper data structure .

in one world, i think it is better to put all the entities in one entity manager domain and isolate them from other thread.

Haynor answered 22/6, 2012 at 0:59 Comment(0)
A
0

have you looked at http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html/transactions.html#transactions-basics-issues. I think it would be wise to read the documentation there before proceeding using sessions object for too much time. I guess the better approach is to use the session to do a simple unit of work (for example : the CRUD operations).

Hope it helps!!.

Greetings.

Andes answered 28/12, 2012 at 20:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.