I spent almost 2 days putting these three together to generate a test application. The beauty about this app is it dose not have any xml configuration file except of course the applicationcontext.xml for spring. And in that file also there is just the datasource defined. I thought of putting it down here in order to save somebody stumbling with the same some time.
What Does the app do?
well its just a test application. It shows how to wire everything together just using the annotations. and it also shows the Ajax functionality and the templating functionality of JSF 2.0. and it also inserts some test entity into the Database
Lets get directly dirty with the code
Lets start with the applicationContext.xml file ..
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource" p:driverClassName="${jdbc.driverClass}" p:password="${jdbc.password}" p:url="${jdbc.url}" p:username="${jdbc.username}"> </bean> <bean class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" id="sessionFactory" p:dataSource-ref="dataSource"> <property name="annotatedClasses"> <list> <value>com.test.car.Car</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=${jdbc.showSql} </value> </property> </bean> <bean class="org.springframework.orm.hibernate3.HibernateTransactionManager" id="transactionManager" p:sessionFactory-ref="sessionFactory"/> <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory" lazy-init="false" p:dataSource-ref="dataSource"> <property name="persistenceUnitName" value="testsource"/> </bean> <!-- Activates annotation-based bean configuration --> <context:annotation-config/> <!-- needed is for @Configurable --> <context:component-scan base-package="com.test"/> <tx:annotation-driven/> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties"/> </bean> </beans>
As you see all you have done is defined your datasource and wired it with entityManagerFactory which will be used by hibernate. All the connection properties are comming from the file jdbc.properties which is looked up from the classpath so it has to be placed inside the classes directory within WEB-INF. The next thing to do is to add the persistance.xml in META-INF folder which looks like this
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="testsource" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <!-- | The SQL dialect to use for this data source, use MySQL InnoDB as | we only use InnoDB tables for the entity beans. +--> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/> <!-- | Specify the second level query cache for hibernate. +--> <!-- | Enable query caching availability. +--> <!-- <property name="hibernate.cache.use_query_cache" value="true"/> --> </properties> </persistence-unit> </persistence>
As you must have noticed here we only declare the persistence-unit name which is used by spring.
And the last xml file is the faces-config.xml. i know i said just one configuration . here we dont define any beans or navaigation rules here we just have our resource bundle and the reslover for faces beans.
<?xml version="1.0"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0"> <application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> <resource-bundle> <base-name>com.test.messages</base-name> <var>msgs</var> </resource-bundle> </application> </faces-config>
so now its all configured. Lets start with the entity class. It looks like this
@Entity @Table(name="user") public class Car implements Serializable{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @NotEmpty @Length(min=1,max=30) private String carName;
next is the DAOimpl class
@Repository public class CarDaoImpl implements CarDao{ private EntityManager entityManagerFactory; @PersistenceContext void setEntityManager(EntityManager entityManager) { this.entityManagerFactory = entityManager; } public void addCar(Car car){ this.entityManagerFactory.persist(car); }
The @Repository annotation is yet another stereotype that was introduced in Spring 2.0 itself. This annotation is used to indicate that a class functions as a repository.
then we have the spring service classes
@Service public class CarServiceImpl implements CarService{ private final CarDao carDao; @Inject CarServiceImpl(CarDao carDao) { this.carDao = carDao; } ...
and finally the backing bean
@ManagedBean("car") @Scope("session") public class CarSession { private Car car; public Car getCar() { return car; } ..
we use annotations for defining managed beans which otherwise would have been declared in ur config file so this significantly reduces your XML, but you can get rid of virtually all of it with JSF 2 through either annotations, as I’m doing for managed beans, or with convention, as is the case for JSF 2’s simplified navigation handling.
so now we have everything in palce .. the only files left are the xhtml files
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" template="/template/masterLayout.xhtml"> <ui:define name="menuLeft"> <!-- <ui:include src="/sections/login/menuLeft.xhtml"/>--> </ui:define> <ui:define name="content"> <ui:include src="/sections/welcome.xhtml"/> </ui:define> </ui:composition>
and the file sections/welcome.xhtml looks like this.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:util="http://java.sun.com/jsf/composite/components/util"> <h:form id="form" prependId="false" > <h:panelGrid> <h:outputText value="#{i18n.prefs_country}"/> <h:selectOneListbox id="company" value="#{car.company}" size="1"> <f:selectItems value="#{facesSupport.carModels}"/> <f:ajax render="model"/> </h:selectOneListbox> <h:outputText value="#{i18n.prefs_region}"/> <h:selectOneListbox id="model" value="#{car.model}" style="width: 180px;" size="1"> <f:selectItems value="#{car.modelOptions}"/> </h:selectOneListbox> </h:panelGrid> <h:commandButton id="loginButton" value="save" action="#{car.saveCar}"/> </h:form></html>
as you see how ajax is used to render the model drop box when ever the company box is changed.
the last thing left is the web.xml file
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/web-application-config.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> <url-pattern>*.faces</url-pattern> </servlet-mapping> <session-config> <session-timeout>500000</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
Thats it .. everything is in place. soon i will zip my test application and upload it so that its easier to go through the code..
Well if there are any questions or suggestions feel free to leave a comment
Finally got some time to create a sample application .. you can download it from here have also included spring security 3.0 into it .. so enjoy ..u can just change from .zip to .war and deploy the application ..but before that dont forget to change the properties file inside /WEB-INF/config add your database connection details there... if there are any questions just write a comment ... and ya .. the source is included inside the war file ... the war file has been tested with tomcat 6 just place it on webapps .. and point ur browser to http://localhost:8080/sample/index.html ..
Very nice post ! thx
Hi, first of all, thank you for your post. I am trying to navigate from one page to another in my jsf+spring project but I couldn’t make it. I put org.springframework.web.jsf.el.SpringBeanFacesELResolver into face-config.xml and navigation rules, but when I return the name of page, it does nothing( I am using jsf2.* and, navigation can make just by returning name of the page as you know). How can I do that. Thank you for your help.
Very Good ! demo !
Cool demo, firstly because it actually works (so many I find don’t actually work), secondly because it’s exactly what I’m looking for (JSF2.0 with Spring3 & Hib 3 using annotations instead of those nasty XMLs!) finally because it’s a proper example rather than the usual ‘Hello World’ that doesn’t really show you much.
Also love the JSTL templates and ui:define etc, never seen that before and it is quality!
Only question I have, can you use the Spring/Hib Services and DAOs without interfaces? Can you inject concrete classes? I tried it but get thefollowing error
“expected at least 1 bean which qualifies as autowire candidate for this dependency”
But was just wondering if it can be done or do you have to have an Interface?
Cheers for the demo!!!
Hi, Thanks for putting up such a nice example. Could please tell me how I can make it as an eclipse project or please provide if possible mavenised version of the project
mark, maybe I don’t know that much.
Try @Autowired
If i remember correct, I’ve done something like you have in the past
(jsf 2 / jpa2-hib /spring 3) and with annotations.
hi, how I can “run/export to war file” it from eclipse?
i am working with tomcat7
i have some problems with de classpath for the properties files.
Excelent demo !
@mark use interfaces for defining dependencies between beans because Spring uses proxies to map them, so if you give the class type and not the interface, Spring will tell you a ClassNotFoundException.
The annotations @Autowire and @Component (or @Service,@Resource, etc) are similar but in wiring method. If you use any @Component tag, don’t use @Autowire.
Sorry for the comment before, it’s wrong, the similar ones are @Autowired and @Resource, don’t remove any @Component anotation. But the interfaces are necessary because of proxies and it’s better to use @Autowire in the injecting methods (as a setter)
Hello! How do you first enter the system? I made a new database.Thanks!
Thank you very much for the post. It really helped to get started and understand how the three work together.
Raza
Hello ,
it is really nice example . i got first time such full combination of example ,but i am facing problem while importing that sample project .can u tell us step for that i will help us
thanks
Hello, in the spring config file,Why use
24
25
26 com.test.car.Car
27
28
this property,……I’m not very understand…could u mail me …I’m a beginer for this
I used to be very happy to search out this web-site.I needed to thanks on your time for this wonderful learn!! I definitely having fun with every little bit of it and I’ve you bookmarked to check out new stuff you weblog post.
Can you put the libraries list that you use? and where do we can find them?
Great demo, good to see something that actually works unlike most ‘demos’ I’ve seen before.
I just have one (pretty silly) question, about the entityManagerFactory.
Can this be renamed to something simpler like ‘em’?
I ask because I renamed it in the DAO and in the applicationContext, but just got an error about em not having a valid setter.
Hi dave,
You have to rename the setter methods as well .. coz from the app context those methods are called for setting the EM .. so they have to be same as the variable name ..
Good demo
Hi,
could we use not @ManagedBean(”car”) bt @Named(”car”) – mean to use CDI instead of just ManagedBean ?
Or CDI and SPRING both the same?
Hi, nice tutorial, but the link for downloading the source code is not working….
Hi
i try to deploy war it gives 404 error.also change database details in gaadi-env.properties file.
can u help to sort out problem