Best way to do database access in a Java desktop application - java

I've been working in Glassfish 3, JPA and Java EE 6. In a web container you can just inject the Entity Manager into an EJB and let that handle your transactions, rollbacks, etc. What do I do in a desktop application. Obviously that does not work. I know I would still use JPA for ORM. But would I create an EntityMangerFactory and then create an Entitymanager from that? Would I have to handle my transactions manually? It would great if I could see some sample applications. Thanks!

EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("DS");
em = entityManagerFactory.createEntityManager();
You have to handle transactions, by calling em.getTransaction.begin() and em.getTransaction.commit(), if you don't use the spring-framework or something else.

Well i suggest to try using Spring +JPA, there you do not need a container ,it is just the application context and you can configure transactions there.
You will not take care of the transactions ,just annotate your methods that you want to be #Transactional.

You could use Spring, this will bring you the plesent you know from JEE6 to desktop applications. (Of course it is not 100% the same!)

Another option could be to use so called Embeddable EJB Container. It could provide you same services as injection, CMT etc which you might be accustomed to.

I've built a 2-tier Java Swing client using Hibernate and Swing, and I will never do it again. If I had to rebuild it today, I would use raw JDBC queries, or maybe a very thin ORM mapping framework like iBatis.
The reason that Hibernate (and I assume other JPA implementations, although my experience is only with Hibernate) is so different in a desktop environment is 1) because objects tend to have a much longer lifespan on the desktop, and 2) it's very hard to know when an object will be accessed, so correct transaction handling for lazy loading is problematic.
The web request-response paradigm is fundamentally transactional, so it's very easy to demarcate your transactions there. On the desktop, every keypress, even just a MouseMovedEvent, could potentially trigger a database query or lazy load, so it's much harder to know when to initiate and commit transactions.
Error handling and object refreshing is a big problem, since objects tend to have a much longer life (often for the duration of the application launch). In Hibernate, exceptions are non-recoverable, which means that you're supposed to reload everything from the db. This is fine on the web, but definitely not fine when you have thousands of objects embedded in various models throughout your GUI.

Related

Replacing Seam with jee6 in conversation

A project I'm working on is going to upgrade from jee5/seam to jee6, where "those who descide" think it is a good idea to drop seam since most of its features have been incorporated into jee6. But I have a case that I doesn't seem to be able to solve in jee6.
We have several wizards using ConversationScope. We use Seams FlushModeType.Manual in order to avoid getting "dirty" data commited until we want we actually wants to commit it (each page-load basically gets it own transaction but since nothing is written to the database until we flush, most commits doesn't change the state of the database).
I have made a few attempts using PersistenceContextType.EXTENDED in jee6 but it seems like I can't find a way to defer the flush to the database like seam does and the only workarounds seems to be to use detached objects or a separate view-model.
We really like how working with attached objects make (for our cases) things really simple to understand and fast to develop.
Is there a solution where we can keep working with attached objects in conversations?
As a big fan of Seam2 I wrote great apps using conversations, conversation scoped entity manager with flush mode set to manual and detached objects.
However, we must now admit that this pattern, despite being strongly pushed in the Seam manual and working great as far as Hibernate is the JPA implementation, is fundamentally broken. The reason is explained in this post from Mark Struberg: Is There A Way To Fix the JPA EntityManager?
So, the answer is no, there is no practical solution to keep working with attached objects in conversations. You should work with detached objects.
There is another another great CDI blogger who experimented with conversation scoped entity manager: Conversational CRUD. It might be worth reading if you keep on trying to work with attached objects.

Best way to handle Hibernate Sessions in a layered Spring MVC Web application

If we have a web application which has
heavy UI (Spring MVC + JQuery with JSON)
Hibernate with JPA annotations being the domain model
extend Spring-provided DAO to code DAO layer
JBOSS being the app server with Oracle as backend
Datasource (JNDI) based connection pooling (Not an XA rather Local data source)
also has access to multiple data sources (dealing with multiple DB)
Behaviorally, lot of Data retrieval (70%) and update of data being 30%
What would be the best practices for the following to effectively consume DB connections and also see to that there is no much leakage at connection usage?
would it be better to opt for Hibernate template based DAOs?
What kind of transaction manager would be suggest-able and should we go for AOP-based transaction managementWhere
where to instantiate session and and where to close the sessions to effectively consume connections from connection pooling.
It is true that we need to handle transactions from Service layer but what happens to sessions would they be waiting for longer time (we are not using any opensessioninviewFilter)
which layer is better to handle the checked exceptions (business exceptions) and runtime exceptions.
Sorry for this being bit lengthier question, however I see that this is being a common query and I tried consolidating it. Appreciate your patience and guidance. Thanks for your help.
This sounds like a pretty typical Spring/Hibernate application, so I would recommend following current best practices, which I recently outlined in another answer. Specifically:
Do not extend Spring DAO support classes or use HibernateTemplate. Use the #Repository annotation combined with component scanning, and directly inject the SessionFactory into your DAO.
Use Spring's HibernateTransactionManager, and definitely use declarative transaction management via #Transactional as your default approach.
Let Spring manage that. It will open sessions just in time for transactions by default, but prefer the open session in view pattern enabled by Spring's OpenSessionInViewFilter.
See #3.
Always handle exceptions where they should be handled--in other words, this is a design decision. Note, however, that the Spring transaction framework by default rolls back on unchecked exceptions, but not checked, to match the behavior of the EJB spec. Make sure to set the proper rollback rules (see previous link) anywhere you use checked exceptions.
Additionally, use a connection pool, obviously. Apache Commons DBCP is a great choice. "Not much leakage in connection usage" isn't enough. You have to have zero connection leakage. Depending on Spring to manage your resources will help ensure this. As for any other performance issues, don't try to optimize prematurely. Wait until you see where your problem areas are, and then figure out the best way to solve each one individually. Since your bottlenecks will most likely be database-related, check out the performance chapter of the Hibernate reference to get an idea what you're up against. It covers the important concepts of caching and fetching strategies.
Use JPA EntityManager directly in your DAOs. Be sure not to mark it as Extended
Prefer <tx:annotation-driven /> and #Transactional - only on the service layer
The transaction manager also opens and closes sessions (if one doesn't exist already in the thread). Here it is good to know that sessions are session-per-request. Each request(=thread) has a separate session instance. But a database connection is created only if one is needed, so even if there is a transaction manager around all methods, needless connections won't be opened.
read-only transactions - use #Transactional(readOnly=true) in cases when there is only data retrieval
caching - utilize hibernate 2nd level cache to put entities in memory (instead of fetching them from the database each time)
avoid OpenSessionInView and lazy collections. This is subjective, but in my opinion all objects that leave the service layer must be initialized. For small collections (for ex. list of roles) you can have eager collections. For bigger collections use HQL queries.

Spring and Hibernate, Lazy initiation problem

Hey I am developing an desktop application using Spring and Hibernate, and I have a problem with lazy initiation. I looked in the web and every solution is related to the open session in view pattern, but I can't use this pattern. I've also tried to get the sessionfactory from the HibernateTemplate, but it returns to me a disconnected session.
Does anyone know other solution?
I would suggest that you basically have two solutions:
Make arrangements to keep a Hibernate session open when you access a lazy-initialized object or collection. That means you're going to have to carefully mark your transaction boundaries in your code, a la the "open session in view" pattern. Spring makes this possible, but in a desktop application it won't be as straightforward as a web application where the transaction boundaries are a little more obvious.
Turn off all the lazy-initialization for your persisted objects in Hibernate.
Option 2 could lead to a lot of unnecessary database access, and option 1 means you have to seriously study your workflow and use cases.
Hope that helps!
One option is to call Hibernate.initialize() on the entities or collections to force initialize them. You'd want to do this before you return the data back to your view. I would consider this carefully, since it's going to generate a lot of SQL statements back to the database.
You may want to look into using "fetch" in your HQL queries or configuration the fetch mode to "eager" in your mappings (I believe it's FetchMode.EAGER in JPA or lazy="false" in hbm.xml).
#Jose: Don't manage the Session in your own ThreadLocal. Use SessionFactory.getCurrentSession() and configure Hibernate to use the "thread" SessionContext.
I had a very similar problem, and as I was not able to find any really appropriate solution to it. I came up with my own one combining a lot of different approaches found on the web and posted them to my blog.
Sorry, that I don't put it in all here, but it is to much work to do it over and over again in all the forums I found people having this or a similar problem
Remote Lazy Loading with Hibernate and Spring

An alternative to Hibernate or TopLink? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Is there a viable alternative to Hibernate? Preferably something that doesn't base itself on JPA.
Our problem is that we are building a complex (as in, many objects refer to each other) stateful RIA system. It seems as Hibernate is designed to be used mainly on one-off applications - JSF and the like.
The problem is mainly that of lazy loading. Since there can be several HTTP requests between the initialization and actually loading lazy collections, a session per transaction is out of the question. A long-lived session (one per application) doesn't work well either, because once a transaction hits a snag and throws an exception, the whole session is invalidated, thus the lazy loaded objects break. Then there's all kinds of stuff that just don't work for us (like implicit data persisting of data from outside an initialized transaction).
My poor explanations aside, the bottom line is that Hibernate does magic we don't like. It seems like TopLink isn't any better, it also being written on top of EJB.
So, a stateless persistence layer (or even bright-enough object-oriented database abstraction layer) is what we would need the most.
Any thoughts, or am I asking for something that doesn't exist?
Edit: I'm sorry for my ambiguous terminology, and thank you all for your corrections and insightful answers. Those who corrected me, you are all correct, I meant JPA, not EJB.
If you're after another JPA provider (Hibernate is one of these) then take a look at EclipseLink. It's far more fully-featured than the JPA 1.0 reference implementation of TopLink Essentials. In fact, EclipseLink will be the JPA 2.0 reference implementation shipped with Glassfish V3 Final.
JPA is good because you can use it both inside and outside a container. I've written Swing clients that use JPA to good effect. It doesn't have the same stigma and XML baggage that EJB 2.0/2.1 came with.
If you're after an even lighter weight solution then look no further than ibatis, which I consider to be my persistence technology of choice for the Java platform. It's lightweight, relies on SQL (it's amazing how much time ORM users spend trying to make their ORM produce good SQL) and does 90-95% of what JPA does (including lazy loading of related entities if you want).
Just to correct a couple of points:
JPA is the peristence layer of EJB, not built on EJB;
Any decent JPA provider has a whole lot of caching going on and it can be hard to figure it all out (this would be a good example of "Why is Simplicity So Complex?"). Unless you're doing something you haven't indicatd, exceptions shouldn't be an issue for your managed objects. Runtime exceptions typically rollback transactions (if you use Spring's transaction management and who doesn't do that?). The provider will maintain cached copies of loaded or persisted objects. This can be problematic if you want to update outside of the entity manager (requiring an explicit cache flush or use of EntityManager.refresh()).
As mentioned, JPA <> EJB, they're not even related. EJB 3 happens to leverage JPA, but that's about it. We have a bunch of stuff using JPA that doesn't even come close to running EJB.
Your problem is not the technology, it's your design.
Or, I should say, your design is not an easy fit on pretty much ANY modern framework.
Specifically, you're trying to keep transactions alive over several HTTP requests.
Naturally, most every common idiom is that each request is in itself one or more transactions, rather than each request being a portion of a larger transaction.
There is also obvious confusion when you used the term "stateless" and "transaction" in the same discussion, as transactions are inherently stateful.
Your big issue is simply managing your transactions manually.
If you transaction is occurring over several HTTP requests, AND those HTTP requests happen to be running "very quicky", right after one another, then you shouldn't really be having any real problem, save that you WILL have to ensure that your HTTP requests are using the same DB connection in order to leverage the Databases transaction facility.
That is, in simple terms, you get a connection to the DB, stuff it in the session, and make sure that for the duration of the transaction, all of your HTTP requests go through not only that same session, but in such a way that the actual Connection is still valid. Specifically, I don't believe there is an off the shelf JDBC connection that will actually survive failover or load balancing from one machine to another.
So, simply, if you want to use DB transactions, you need to ensure that your using the same DB Connection.
Now, if your long running transaction has "user interactions" within it, i.e. you start the DB transaction and wait for the user to "do something", then, quite simply, that design is all wrong. You DO NOT want to do that, as long lived transactions, especially in interactive environments, are just simply Bad. Like "Crossing The Streams" Bad. Don't do it. Batch transactions are different, but interactive long lived transactions are Bad.
You want to keep your interactive transactions as short lived as practical.
Now, if you can NOT ensure you will be able to use the same DB connection for your transaction, then, congratulations, you get to implement your own transactions. That means you get to design your system and data flows as if you have no transactional capability on the back end.
That essentially means that you will need to come up with your own mechanism to "commit" your data.
A good way to do this would be where you build up your data incrementally into a single "transaction" document, then feed that document to a "save" routine that does much of the real work. Like, you could store a row in the database, and flag it as "unsaved". You do that with all of your rows, and finally call a routine that runs through all of the data you just stored, and marks it all as "saved" in a single transaction mini-batch process.
Meanwhile, all of your other SQL "ignores" data that is not "saved". Throw in some time stamps and have a reaper process scavenging (if you really want to bother -- it may well be actually cheaper to just leave dead rows in the DB, depends on volume), these dead "unsaved" rows, as these are "uncomitted" transactions.
It's not as bad as it sounds. If you truly want a stateless environment, which is what it sounds like to me, then you'll need to do something like this.
Mind, in all of this the persistence tech really has nothing to do with it. The problem is how you use your transactions, rather than the tech so much.
I think you should have a look at apache cayenne which is a very good alternative to "big" frameworks. With its decent modeler, the learning curve is shorten by a good documentation.
I've looked at SimpleORM last year, and was very impressed by its lightweight no-magic design. Now there seems to be a version 3, but I don't have any experience with that one.
Ebean ORM (http://www.avaje.org)
It is a simpler more intuitive ORM to use.
Uses JPA Annotations for Mapping (#Entity, #OneToMany etc)
Sessionless API - No Hibernate Session or JPA Entity Manager
Lazy loading just works
Partial Object support for greater performance
Automatic Query tuning via "Autofetch"
Spring Integration
Large Query Support
Great support for Batch processing
Background fetching
DDL Generation
You can use raw SQL if you like (as good as Ibatis)
LGPL licence
Rob.
BEA Kodo (formerlly Solarmetric Kodo) is another alternative. It supports JPA, JDO, and EJ3. It is highly configurable and can support agressive pre-fetching, detaching/attaching of objects, etc.
Though, from what you've described, Toplink should be able to handle your problems. Mostly, it sounds like you need to be able to attach/detach objects from the persistence layer as requests start and end.
Just for reference, why the OP's design is his biggest problem: spanning transactions across multiple user requests means you can have as many open transactions at a given time as there are users connected to your app - a transaction keeps the connection busy until it is committed/rolled back. With thousand of simultaneously connected users, this can potentially mean thousands of connections. Most databases don't support this.
Neither Hibernate nor Toplink (EclipseLink) is based on EJB, they are both POJO persistancy frameworks (ORM).
I agree with the previous answer: iBatis is a good alternative to ORM frameworks: full control over sql, with a good caching mechanism.
One other option is Torque, I am not saying it is better than any of the options mentioned above but just that it is another option to look at.
It is getting quite old now but may fit some of your requirements.
Torque
When I was myself looking for a replacement to Hibernate I stumbled upon DataNucleus Access Platform, which is an Apache2-licensed ORM. It isn't just ORM as it provides persistence and retrieval of data also in other datasources than RDBMS, like LDAP, DB4O and XML. I don't have any usage experience, but it looks interesting.
Consider breaking your paradigm completely with something like tox. If you need Java classes you could load the XML result into JDOM.

What's the best way to share business object instances between Java web apps using JBoss and Spring?

We currently have a web application loading a Spring application context which instantiates a stack of business objects, DAO objects and Hibernate. We would like to share this stack with another web application, to avoid having multiple instances of the same objects.
We have looked into several approaches; exposing the objects using JMX or JNDI, or using EJB3.
The different approaches all have their issues, and we are looking for a lightweight method.
Any suggestions on how to solve this?
Edit: I have received comments requesting me to elaborate a bit, so here goes:
The main problem we want to solve is that we want to have only one instance of Hibernate. This is due to problems with invalidation of Hibernate's 2nd level cache when running several client applications working with the same datasource. Also, the business/DAO/Hibernate stack is growing rather large, so not duplicating it just makes more sense.
First, we tried to look at how the business layer alone could be exposed to other web apps, and Spring offers JMX wrapping at the price of a tiny amount of XML. However, we were unable to bind the JMX entities to the JNDI tree, so we couldn't lookup the objects from the web apps.
Then we tried binding the business layer directly to JNDI. Although Spring didn't offer any method for this, using JNDITemplate to bind them was also trivial. But this led to several new problems: 1) Security manager denies access to RMI classloader, so the client failed once we tried to invoke methods on the JNDI resource. 2) Once the security issues were resolved, JBoss threw IllegalArgumentException: object is not an instance of declaring class. A bit of reading reveals that we need stub implementations for the JNDI resources, but this seems like a lot of hassle (perhaps Spring can help us?)
We haven't looked too much into EJB yet, but after the first two tries I'm wondering if what we're trying to achieve is at all possible.
To sum up what we're trying to achieve: One JBoss instance, several web apps utilizing one stack of business objects on top of DAO layer and Hibernate.
Best regards,
Nils
Are the web applications deployed on the same server?
I can't speak for Spring, but it is straightforward to move your business logic in to the EJB tier using Session Beans.
The application organization is straight forward. The Logic goes in to Session Beans, and these Session Beans are bundled within a single jar as an Java EE artifact with a ejb-jar.xml file (in EJB3, this will likely be practically empty).
Then bundle you Entity classes in to a seperate jar file.
Next, you will build each web app in to their own WAR file.
Finally, all of the jars and the wars are bundled in to a Java EE EAR, with the associated application.xml file (again, this will likely be quite minimal, simply enumerating the jars in the EAR).
This EAR is deployed wholesale to the app server.
Each WAR is effectively independent -- their own sessions, there own context paths, etc. But they share the common EJB back end, so you have only a single 2nd level cache.
You also use local references and calling semantic to talk to the EJBs since they're in the same server. No need for remote calls here.
I think this solves quite well the issue you're having, and its is quite straightforward in Java EE 5 with EJB 3.
Also, you can still use Spring for much of your work, as I understand, but I'm not a Spring person so I can not speak to the details.
What about spring parentContext?
Check out this article:
http://springtips.blogspot.com/2007/06/using-shared-parent-application-context.html
Terracotta might be a good fit here (disclosure: I am a developer for Terracotta). Terracotta transparently clusters Java objects at the JVM level, and integrates with both Spring and Hibernate. It is free and open source.
As you said, the problem of more than one client web app using an L2 cache is keeping those caches in synch. With Terracotta you can cluster a single Hibernate L2 cache. Each client node works with it's copy of that clustered cache, and Terracotta keeps it in synch. This link explains more.
As for your business objects, you can use Terracotta's Spring integration to cluster your beans - each web app can share clustered bean instances, and Terracotta keeps the clustered state in synch transparently.
Actually, if you want a lightweight solution and don't need transactions or clustering just use Spring support for RMI. It allows to expose Spring beans remotely using simple annotations in the latest versions. See http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html.
You should take a look at the Terracotta Reference Web Application - Examinator. It has most of the components you are looking for - it's got Hibernate, JPA, and Spring with a MySQL backend.
It's been pre-tuned to scale up to 16 nodes, 20k concurrent users.
Check it out here: http://reference.terracotta.org/examinator
Thank you for your answers so far. We're still not quite there, but we have tried a few things now and see things more clearly. Here's a short update:
The solution which appears to be the most viable is EJB. However, this will require some amount of changes in our code, so we're not going to fully implement that solution right now. I'm almost surprised that we haven't been able to find some Spring feature to help us out here.
We have also tried the JNDI route, which ends with the need for stubs for all shared interfaces. This feels like a lot of hassle, considering that everything is on the same server anyway.
Yesterday, we had a small break through with JMX. Although JMX is definately not meant for this kind of use, we have proven that it can be done - with no code changes and a minimal amount of XML (a big Thank You to Spring for MBeanExporter and MBeanProxyFactoryBean). The major drawbacks to this method are performance and the fact that our domain classes must be shared through JBoss' server/lib folder. I.e., we have to remove some dependencies from our WARs and move them to server/lib, else we get ClassCastException when the business layer returns objects from our own domain model. I fully understand why this happens, but it is not ideal for what we're trying to achieve.
I thought it was time for a little update, because what appears to be the best solution will take some time to implement. I'll post our findings here once we've done that job.
Spring does have an integration point that might be of interest to you: EJB 3 injection nterceptor. This enables you to access spring beans from EJBs.
I'm not really sure what you are trying to solve; at the end of the day each jvm will either have replicated instances of the objects, or stubs representing objects existing on another (logical) server.
You could, setup a third 'business logic' server that has a remote api which your two web apps could call. The typical solution is to use EJB, but I think spring has remoting options built into its stack.
The other option is to use some form of shared cache architecture... which will synchronize object changes between the servers, but you still have two sets of instances.
Take a look at JBossCache. It allows you to easily share/replicate maps of data between mulitple JVM instances (same box or different). It is easy to use and has lots of wire level protocol options (TCP, UDP Multicast, etc.).

Categories

Resources