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.
Related
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.
I asked a question yesterday ( Using Spring in standalone apps ) on how you would use Spring in a standalone application. From that I learned that you only create the application context object once. So now the question is (even though it was partially answered in a comment) what happens when you create the application context?
Does Spring create the beans and wire them together when you say
new ClassPathXmlApplicationContext("some.xml") ?
I am not sure if I understand the boot strapping, and why it is like that.
The idea behind the ApplicationContext in Spring is that in order to properly inject objects where they are needed, some thing needs to be aware of the configuration the user specifies and inject dependencies based on this configuration.
The ApplicationContext is the thing that understands the user's wishes in terms of where and what should be injected (as well as other things such as AOP pointcuts and such) based on the configuration a user provides, either through an xml file or annotations.
Yes it will parse the bean definition file , it will create the beans , give them the dependencies,
The easiest way to debug is to go with the output print statements,
Put the statements in constructor & setter methods and try different possibilities to track the flow
I'm currently in the process of creating a data access layer for an application. This application will initially connect to an Oracle database but will later also connect to a DB2 database.
For connecting to the database I will use JDBC. At this time I'm considering my options. As I see it I have two (primary) options.
1) Create a design with support for multiple DAO factories, each instantiating the DAO's specific to their database. Initially, this design will only have one factory. Later it will be extended with a second factory and DAO classes.
2) Create one DAO factory which instantiates multiple DAO's for the different models. This DAO factory builds the DAO's based on a configuration file, which contains the JDBC driver path and connection url.
I'm tempted to choose the second option, which seems to remove quite some code duplication in the DAO's. Could anyone give the pros and cons of both approaches?
Why would you choose for multiple DAO factories (abstract factory pattern) when you don't really need it when using JDBC?
I believe Spring or Guice would be the best and cleanest option for you, where you'd want to pick the appropriate DAO implementation and inject it in the DAO consumer layer. Spring will also enable you to use Spring-JDBC which takes care of most of the boilerplate code making your DAO Impls easy to manage and code. You can also use ORMs with Spring.
Taking into account that you can't use Spring (even though it would save you from a lot of coding), I would say that 2nd variant is more appropriate to you, because you are going to implement dependecy management yourself and 1 dependency (single DAO factory) is always easier than 2.
Though, if you expect that amount of places were DAOs for both databases are used together is not big, then separating them into 2 factories will have a better structural meaning and is more clean. But if you expect, that pretty much every class that uses DAOs will need both worlds (Oracle + DB2), then again stick to the 2nd variant.
In any case, try to consider again about dependecy injection framework usage, because that what you are going to implement yourself anyway with all your factories.
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 looking at this java web application that is using hibernate, jsp's, and spring framework. (from what I can tell!)
the file layout is like this:
classes/com/example/project1
inside project1
/dao
_entity_Dao.java
/dao/hibernate/
_entity_DaoHibernate.java
/factory
DaoFactory.java
DaoFactoryImpl.java
/managers
_entity_Manager.java
/managers/impl
_entity_ManagerImpl.java
/model
_entity_.java
/service
_xxxx_Service.java
/service/impl/
_xxxx_ServiceImpl.java
Have you guys read about this sort of layout somewhere? Is it considered best-practice?
What is the difference between a Factory and a Manager and a Service? (high level)
For typical layout of an application built with Spring I'd look at the example web applications that ship with it (meaning Spring).
Using things like DaoFactory is definitely not be a best-practice, the Daos should get injected instead. In general you should not need factories with Spring except for some unusual cases. Injecting is done when the web application starts up, spring reads the configuration information and constructs all the objects and plugs them in according to configuration xml and/or annotations (this is assuming singleton-scope for your objects, which is usual for stateless things like daos and services, things scoped as prototypes get new copies created as the application asks for them).
In Spring applications a service is similar to a Stateless Session Bean, it is a transactional layer encompassing application logic for a use case. So if your user takes an action that has the effect of causing several different tables to get updated you can inject the daos into that service, have a method on that service do the updates on the daos, and configure Spring to wrap that service in a proxy that makes that method transactional.
I've seen manager used as another name for what I described as service. Here I don't know what they're doing with it.
I don't like the idea of combining your interfaces and impls in one project. Just because you want to consume the interface doesn't mean you want to consume the impl and it's cumbersome transitive dependencies. The main reason is because there will be more than one impl (hypothetically, i.e. JPA/JDBC/Hibernate, or Axis2/CXF, etc.). The interfaces should not be bound to the implementation, otherwise the point is lost. This also allows for easy dependency injection as the impls simply reside on the classpath, then something like a Proxy or Spring (e.g.) can inject the implementations.
In all likelihood, all you need is a:
Interface Project
dao
EntityDao
types
Entity
HibernateImpl Project
dao
EntityHibernateDao
src/main/resources/
EntityMapping.cfg.xml