Posts Tagged ‘JSF’
(long tweet) When ‘filter’ does not work with Primefaces’ datatable
Abstract
Sometimes, the filter
function in Primefaces <p:datatable/>
does not work when the field on which filtering is operated typed as an enum
.
Explanation
Actually, in order to filter, Primefaces relies on a direct '='
comparison. The hack to fix this issue is to force Primefaces to compare on the enum name, and not by a reference check.
Quick fix
In the enum class, add the following block:
public String getName(){ return name(); }
Have the datatable declaration to look like:
<p:dataTable id="castorsDT" var="castor" value="#{managedCastorListManagedBean.initiatedCastors}" widgetVar="castorsTable" filteredValue="#{managedCastorListManagedBean.filteredCastors}">
Declare the enum-filtered column lke this:
<p:column sortBy="#{castor.castorWorkflowStatus}" filterable="true" filterBy="#{castor.castorWorkflowStatus.name}" filterMatchMode="in"> <f:facet name="filter"> <p:selectCheckboxMenu label="#{messages['status']}" onchange="PF('castorsTable').filter()"> <f:selectItems value="#{transverseManagedBean.allCastorWorkflowStatuses}" var="cws" itemLabel="#{cws.name}" itemValue="#{cws.name}"/> </p:selectCheckboxMenu> </f:facet> </p:column>
Notice how the filtering
attribute is declared:
filterable="true" filterBy="#{castor.castorWorkflowStatus.name}" filterMatchMode="in"
In other terms, the comparison is forced the rely on equals()
of class String
, through the calls to getName()
and name()
.
(long tweet) Could not find backup for factory javax.faces.context.FacesContextFactory.
Case
On deploying a JSF 2.2 / Primefaces 5 application on Jetty 9, I got the following error:
java.lang.IllegalStateException: Could not find backup for factory javax.faces.context.FacesContextFactory.
The issue seems linked to Jetty, since I could not reproduce the issue on Tomcat 8.
Quickfix
In the web.xml
, add the following block:
<listener> <listener-class>com.sun.faces.config.ConfigureListener</listener-class> </listener>
MultiException[java.lang.RuntimeException: Error scanning file]
Case
I run a project with JSF 2 / PrimeFaces 5 (BTW: it rocks!) / Spring 4 / Jetty 9 / Java 8:
MultiException java.lang.RuntimeException: Error scanning file SummerBean.class, java.lang.RuntimeException: Error scanning entry .../SummerService.class from jar file:/.../spring-tier-1.0-SNAPSHOT.jar, java.lang.RuntimeException: Error scanning entry .../SummerServiceImpl.class from jar file:/.../spring-tier-1.0-SNAPSHOT.jar at org.eclipse.jetty.annotations.AnnotationConfiguration.scanForAnnotations(AnnotationConfiguration.java:530)
Explanation
The error occurs because of a conflict on the JARs of ASM.
Fix
You have to override Jetty’s dependencies to ASM.
In Maven’s POM, amend Jetty plugin to force ASM versions:
<plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>${jetty.version}</version> <dependencies> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>5.0.2</version> </dependency> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm-commons</artifactId> <version>5.0.2</version> </dependency> </dependencies> <!-- ... --> </plugin>
Then it should work 😉
(long tweet) How to use comments in JSF 2?
If you write comments in an XHTML file (used by JSF2) as regular XML comments (ie starting with <!--
and ending with -->
), you may probably find them in the HTML source generated “by” JSF. To prevent that, add the following bloxk in your web.xml
:
<context-param> <param-name>facelets.SKIP_COMMENTS</param-name> <param-value>true</param-value> </context-param>
(quick tutorial) Migration from MySQL to HSQLDB
Case
I got the project described in MK Yong’s website. This projects is a sample code of JSF + Spring + Hibernate. The laying DB is a MySQL. For many reasons, I’d rather not to detail, I prefered to a HSQLDB instead of the MySQL.
(Notice: the zip you can download at MK Yong’s website contains many errors, not related to the persistance layer but to JSF itself.)
How to migrate any project from MySQL to HSQLDB?
Solution
You have to follow these steps:
Maven
In the pom.xml
, replace:
<!-- MySQL database driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency>
with:
<!-- driver for HSQLdb --> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.2.8</version> </dependency>
By the way, you can add Jetty plugin to have shorter development cycles:
<plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <configuration> <webApp>${basedir}/target/jsf.war</webApp> <port>8088</port> </configuration> </plugin>
Persistence
Properties
Replace the content of db.properties
file with:
jdbc.driverClassName=org.hsqldb.jdbcDriver jdbc.url=jdbc:hsqldb:hsql://localhost:9001 jdbc.username=sa jdbc.password=
Hibernate Mapping
In the *.hbm.xml
files:
- in the tag
<class>
, remove the attributecatalog="..."
- replace the types with fully qualified object types, eg:
long
withjava.lang.Long
,string
withjava.lang.String
,timestamp
withjava.util.Date
,- etc.
Hibernate Properties
For the property of key hibernate.dialect
, replace the value: org.hibernate.dialect.MySQLDialectorg.hibernate.dialect.HSQLDialect
with the value: org.hibernate.dialect.HSQLDialect
.
To match my needs, I tuned Hibernate properties a bit more, but it may not be needed in all situations:
<property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hbm2ddl.auto">create-drop</prop> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> <prop key="connection.pool_size">1</prop> <prop key="current_session_context_class">thread</prop> <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop> </props> </property>
Run
Run the HSQLDB server. IMHO, the quickest is to run the following Maven command:
mvn exec:java -Dexec.mainClass="org.hsqldb.Server"
But you may prefer the old school java -cp hsqldb-XXX.jar org.hsqldb.Server
;-).
Tip! To get a GUI to check the content of the DB instance, you can run:
mvn exec:java -Dexec.mainClass="org.hsqldb.util.DatabaseManager"
Then build and launch Jetty:
mvn clean install jetty:run-exploded
Here you can see the great feature of HSQLDB, that will allow you to create, alter and delete tables on the fly (if hibernate.hbm2ddl.auto
is set to create-drop
), without any SQL scripts, but only thanks to HBM mapping files.