I am trying to use the org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy in my Spring project, but I am not sure how to use it or whether it's exactly what I am looking for. I realize it can help make my DAOs work with a plain JDO PersistenceManagerFactory. Another question is: what happens if the proxy doesn't get made properly? Can I still use it to access my factory to create a transaction aware persistence manager? If the object managed by the factory is a singleton, does this change things? Why not just access the PersistenceManagerFactory directly? Perhaps PersistenceManagerFactoryUtils.getPersistenceManager would be more suited to my needs? Can getObject return null?
Answers are directly available on documentation
I realize it can help make my DAOs work with a plain JDO PersistenceManagerFactory.
Yes.
TransactionAwarePersistenceManagerFactoryProxy proxy allows DAOs to work with a plain JDO PersistenceManagerFactory reference, while still participating in Spring's (or a J2EE server's) resource and transaction management.
You can surely use it in your app. But without knowing your exact needs, we can't confirm any further.
Can I still use it to access my factory to create a transaction aware persistence manager
DAOs could seamlessly switch between a JNDI PersistenceManagerFactory and this proxy for a local PersistenceManagerFactory.
If the object managed by the factory is a singleton, does this change things? Why not just access the PersistenceManagerFactory directly?
It is usually preferable to write your JDO-based DAOs with Spring's JdoTemplate, offering benefits such as consistent data access exceptions instead of JDOExceptions at the DAO layer. However, Spring's resource and transaction management (and Dependency Injection) will work for DAOs written against the plain JDO API as well.
Related
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.
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.
Can someone outline the steps required to get hibernate working with spring mvc.
I've seen EntityDao's that basically inherit from a GenericDAo.
The generic Dao has basic operations like GetAll, GetByID, Save, Delete, etc.
And inside their methods they use:
getHibernateTemplate
So basically the Session has to be wired up in a bean, and mysql settings have to be set.
I find the spring documentation to be a little confusing: http://static.springsource.org/spring/docs/3.0.0.RELEASE/spring-framework-reference/html/orm.html#orm-hibernate
The basic components are:
Something to configure and create the Hibernate SessionFactory. This is typically done by the LocalSessionFactoryBean, as used in the example in the link you posted. This exposes a Spring-managed bean that implements the Hibernate SessionFactory interface.
Typically, you then have one or more DAO beans which are injected with the SessionFactory. In many cases, the simplest thing to do here is to extend the convenient HibernateDaoSupport class, which has a sessionFactory property. HibernateDaoSupport proves a getHibernateTemplate() method, which gets a Hibernate Session from the SessionFactory and wraps it in a HibernateTemplate object, which provides various convenience methods for doing common Hibernate operations, and is generally more useful than the raw Session interface.
Using this pattern, there is very little direct interaction between application code and the Hibernate API itself, its mostly done though s Spring intermediate layer. Some would call this a good thing, others would rather Spring stayed out of the way. This is a perfectly good alternative - there's nothing to stop you injecting your bean with SessionFactory and using the Hibernate API directly. The HibernateDaoSupport and HibernateTemplate classes are there purely as a convenience.
There is another way. If you don't want to use HibernateDaoSupport then you could directly inject SessionFactory into your DAO classes. This avoids tying you down to Spring classes.
Refer this for example - Spring Doc
This shows how to use Hibernate APIs directly.
Hope that helps.
I'm working on a web application that uses Spring MVC 2.5 and Hibernate.
One of the requirements of the application is that it must be able to export some objects to an external database. I figure I might as well use my existing data layer and just save the objects to the external source.
I'm new to Spring and Hibernate, and I guess I'm just wondering how I should approach this. Right now everything is automatically wired up through annotations. I'm guessing I'll have to create a new dataSource bean, and a new sessionFactory, and a transactionManager...maybe...but...
I only want the connection to the external data source to be available when the user is specifically "exporting".
Is autowiring going to get in my way? How can I tell Spring to inject the appropriate sessionFactory when I instantiate a DAO for my export process? (I'm autowiring through constructors) Should I programatically create my session factory (etc) and then manually instantiate my DAO? If so, will this "override" the autowire annotation?
I guess I don't need answers to the above questions specifically if someone can just step me through the basic process of getting something like this to work. Thanks!
Spring fortunately already has a solution for this: AbstractRoutingDataSource. It basically acts as a Facade for multiple DataSources and allows you to subclass it and implement whatever logic you need to decide which DataSource should be used. Some details are here:
http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/
This allows your DataSource lookup logic to be handled in exactly one place. Your DAO layer and SessionFactory do not need to be adjusted, except that you need to inject your subclass of AbstractRoutingDataSource into the Hibernate SessionFactory.
Configuring multiple data sources and session factories in your spring context will not itself be a problem, but it does make autowiring less attractive.
You could use the #Qualifier annotation to tell the autowiring which one to choose, but I'd suggest not using autowiring, and instead explicitly injecting the correct data source and session factory using <property> or <constructor-arg>.
The transaction manager could potentially be shared between both data sources, if both data sources are managed by your app server, but it sounds like having transactional integrity across both data sources is not a requirement for you, and that having separate transactions for each data source would be enough.
I have a SEAM app with some JPA/Hibernate entities. And I now wonder where to put my query, persistence methods.
The default choice seems to put them in a session bean layer with injected
#PersistenceContext(...) #Inject EntityManager entityManager;
But I think I would rather have the methods on the entities themselves. What are the pro's/con's?
Testablity?
Niceness?
Performance?
And does anyone have links to best practices for interacting with the EntityManager etc. from methods on the Entities rather than session beans?
Best,
Anders
I have no experience with SEAM, but from my experience with Java projects, I found it easiest to keep beans clear of persist methods. What we usually do:
Have beans for business objects (like "User" and "Setting" for example)
Have a DAO layer which can persist and retrieve these beans (simple CRUD)
Have a Service Layer which nows how to handle the beans, and maybe even how to build an aggregate of beans
This way, everything is pretty separated, and is easy to unittest. Performance is usually not an issue with this setup.
Yes, that is also what I have done before.
In general, I think, EJB is insanely verbose and boilerplate'y, but SEAM actually helps a bit, so that is why, in my current project, the extra layer of session beans just to query and persist annoys me. I have the feeling that I could make a reasonably concise app if I could kill this layer...