Creating a sample Java EE 6 Blog Application with JPA, EJB, CDI, JSF and Primefaces on GlassFish

February 8th, 2011 by

Java EE 6 is out and it indeed offers an interesting stack of technologies. So in today’s tutorial we are going to build a small sample web application that builds on this stack using Enterprise JavaBeans, Java Persistence API, Bean Validation, CDI and finally Java Server Faces and PrimeFaces.

The application we’re going to develop is a simple blog app that allows us to create new articles, list them and – finally delete them. We’re also covering some additional topics like JSF navigation, i18n, Ajax-enabled components and the deployment on the GlassFish application server.

 

Prerequisites

We do not need anything exotic for this tutorial .. just a JDK, Maven and a GlassFish. I’ve chosen the last one because of its status as Java EE 6 reference implementation but inbetween JBoss released a new version that supports the Java EE 6 Web Profile so perhaps it is also worth a look …

Our Technology Stack

We’re going to cover a lot of specifications so here is a brief overview of technologies used in the following tutorial:

Build management: Maven, Maven EJB Plugin and others ..

Application Server: GlassFish 3 (running on my Ubuntu machine)

Persistence: Java Persistence API as abstraction layer, TopLink/EclipseLink as persistence provider, JavaDB/Derby as concrete underlying RDBMS

Inversion of Control/Dependency Injection: CDI specs using Weld

Validation: Bean Validation / JSR 303

Presentation Tier: Java Server Faces 2 / Mojarra and PrimeFaces 2.2

Middle Tier: Enterprise Java Beans 3.1

Project Setup using Maven Archetypes

We’re too lazy to create a project skeleton and add dependencies by hand so we’re using an archetype to create our project..

  • Create a new Maven project using the webapp-javaee6 (org.codehaus.mojo.archetype:webapp-javaee6) archetype with your favourite IDE and Maven plugin or via console
    mvn archetype:generate
    [INFO] Scanning for projects...
    [..]
    254: remote -> webapp-javaee6 (Archetype for a web application using Java EE 6.)
    [..]
    Choose version:
    1: 1.0
    2: 1.0.1
    3: 1.0.2
    4: 1.1
    5: 1.2
    6: 1.3
    Choose a number: 6: 6
    Define value for property 'groupId': : com.hascode.tutorial.jee6
    Define value for property 'artifactId': : jee6-blog-tutorial
    Define value for property 'version': 1.0-SNAPSHOT: 0.0.1
    Define value for property 'package': com.hascode.tutorial.jee6: com.hascode.tutorial.jee6.blog
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
  • Add the following dependencies and repositories – your pom.xml should look like this one
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
     
    	<groupId>com.hascode.tutorial.jee6</groupId>
    	<artifactId>jee6-blog-tutorial</artifactId>
    	<version>0.0.1</version>
    	<packaging>war</packaging>
     
    	<name>hasCode.com Java EE 6 Blog Tutorial</name>
     
    	<properties>
    		<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    	</properties>
     
    	<dependencies>
    		<dependency>
    			<groupId>javax</groupId>
    			<artifactId>javaee-web-api</artifactId>
    			<version>6.0</version>
    			<scope>provided</scope>
    		</dependency>
    		<dependency>
    			<groupId>javax.validation</groupId>
    			<artifactId>validation-api</artifactId>
    			<version>1.0.0.GA</version>
    			<scope>provided</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.hibernate</groupId>
    			<artifactId>hibernate-validator</artifactId>
    			<version>4.0.2.GA</version>
    		</dependency>
    		<dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>4.8.2</version>
    			<scope>test</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.derby</groupId>
    			<artifactId>derby</artifactId>
    			<version>10.6.1.0</version>
    		</dependency>
    		<dependency>
    			<groupId>org.primefaces</groupId>
    			<artifactId>primefaces</artifactId>
    			<version>2.2</version>
    		</dependency>
    		<dependency>
    			<groupId>javax.faces</groupId>
    			<artifactId>jsf-api</artifactId>
    			<version>2.0</version>
    			<scope>provided</scope>
    		</dependency>
    	</dependencies>
     
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>2.3.2</version>
    				<configuration>
    					<source>1.6</source>
    					<target>1.6</target>
    					<compilerArguments>
    						<endorseddirs>${endorsed.dir}</endorseddirs>
    					</compilerArguments>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-war-plugin</artifactId>
    				<version>2.1</version>
    				<configuration>
    					<failOnMissingWebXml>false</failOnMissingWebXml>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-dependency-plugin</artifactId>
    				<version>2.1</version>
    				<executions>
    					<execution>
    						<phase>validate</phase>
    						<goals>
    							<goal>copy</goal>
    						</goals>
    						<configuration>
    							<outputDirectory>${endorsed.dir}</outputDirectory>
    							<silent>true</silent>
    							<artifactItems>
    								<artifactItem>
    									<groupId>javax</groupId>
    									<artifactId>javaee-endorsed-api</artifactId>
    									<version>6.0</version>
    									<type>jar</type>
    								</artifactItem>
    							</artifactItems>
    						</configuration>
    					</execution>
    				</executions>
    			</plugin>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-ejb-plugin</artifactId>
    				<configuration>
    					<ejbVersion>3.1</ejbVersion>
    					<archive>
    						<manifest>
    							<addClasspath>true</addClasspath>
    						</manifest>
    					</archive>
    				</configuration>
    			</plugin>
    		</plugins>
    		<finalName>jee6-blog-tutorial</finalName>
    	</build>
     
    	<repositories>
    		<repository>
    			<id>maven2-repository.dev.java.net</id>
    			<name>Java.net Repository for Maven</name>
    			<url>http://download.java.net/maven/2</url>
    		</repository>
    		<repository>
    			<id>JBoss repository</id>
    			<url>http://repository.jboss.com/maven2/</url>
    		</repository>
    		<repository>
    			<id>EclipseLink Repo</id>
    			<url>http://www.eclipse.org/downloads/download.php?r=1&amp;nf=1&amp;file=/rt/eclipselink/maven.repo</url>
    			<snapshots>
    				<enabled>true</enabled>
    			</snapshots>
    		</repository>
    		<repository>
    			<id>primefaces-repo</id>
    			<name>Prime Technology Maven Repository</name>
    			<url>http://repository.primefaces.org</url>
    			<layout>default</layout>
    		</repository>
    	</repositories>
    </project>
  • Remove the created index.jsp from src/main/webapp and add the directories for resources, WEB-INF and META-INF
    mkdir -p src/main/resources
    mkdir -p src/main/webapp/WEB-INF
    mkdir -p src/main/resources/META-INF
  • Create an empty file named beans.xml in src/main/webapp/WEB-INF – we need it for CDI .. you’re asking why? Gavin King kindly gives an explaination.
    touch src/main/webapp/WEB-INF/beans.xml

Entity creation using the Java Persistence API 2 / JSR-317

We want to save our blog entries in the persistence layer .. what we’re going to store is a title, the author, the date the entry was created and of course some text content.

  • First create a new class named BlogEntry in the package com.hascode.tutorial.jee6.blog.entity
    package com.hascode.tutorial.jee6.blog.entity;
     
    import java.io.Serializable;
    import java.util.Date;
     
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Lob;
    import javax.persistence.PrePersist;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
     
    @Entity
    public class BlogEntry implements Serializable {
    	private static final long	serialVersionUID	= 1L;
     
    	@Id
    	@GeneratedValue
    	private Long				id;
     
    	private String				title;
     
    	@Lob
    	private String				content;
     
    	private String				author;
     
    	@Temporal(TemporalType.TIMESTAMP)
    	private Date				created = new Date();
     
    	@PrePersist
    	private void onCreate() {
    		created = new Date();
    	}
     
    	/**
    	 * @param id
    	 *            the id to set
    	 */
    	public void setId(Long id) {
    		this.id = id;
    	}
     
    	/**
    	 * @return the title
    	 */
    	public String getTitle() {
    		return title;
    	}
     
    	/**
    	 * @param title
    	 *            the title to set
    	 */
    	public void setTitle(String title) {
    		this.title = title;
    	}
     
    	/**
    	 * @return the content
    	 */
    	public String getContent() {
    		return content;
    	}
     
    	/**
    	 * @param content
    	 *            the content to set
    	 */
    	public void setContent(String content) {
    		this.content = content;
    	}
     
    	/**
    	 * @return the author
    	 */
    	public String getAuthor() {
    		return author;
    	}
     
    	/**
    	 * @param author
    	 *            the author to set
    	 */
    	public void setAuthor(String author) {
    		this.author = author;
    	}
     
    	/**
    	 * @return the created
    	 */
    	public Date getCreated() {
    		return created;
    	}
     
    	/**
    	 * @param created
    	 *            the created to set
    	 */
    	public void setCreated(Date created) {
    		this.created = created;
    	}
     
    	/**
    	 * @return the id
    	 */
    	public Long getId() {
    		return id;
    	}
    }

So what have we done here?

  • The minimal set of annotations we need is @Entity and @Id - we have added those to the entity class and to the field id
  • We don’t want to set our primary key by hand so we’re adding the @GeneratedValue annotation to our id
  • The text from a blog entry might take some space so we’re predicting that with the @LoB annotation
  • We want to save the creation date of a blog entry as a timestamp and not a date – that’s why we add @Temporal(TemporalType.TIMESTAMP)
  • To set the creation date on our first persist we’re using @PrePersist

Now we need to define a persistence unit ..

  • First we create a new xml file named persistence.xml in src/main/resources/META-INF
  • We’re using EclipseLink/TopLink as PersistenceProvider
  • Because we’re lazy we’re going to use the GlassFish embedded database “__default” via JNDI “jdbc/__default”. SCREENSHOT
  • Out persistence unit is named “defaultPersistenceUnit
  • We definitely want container managed transactions/CTM here that’s why we choose JTA as transaction-type
  • At last we want EclipseLink to create the tables for our entity so the value for the property eclipselink.ddl-generation is “create-tables“. You might want to change this for another persistence unit for integration tests later.
  • Finally the persistence.xml should look like this one
    <?xml version="1.0" encoding="UTF-8"?>
    <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="defaultPersistenceUnit"
    		transaction-type="JTA">
    		<provider>oracle.toplink.essentials.PersistenceProvider</provider>
    		<jta-data-source>jdbc/__default</jta-data-source>
    		<class>com.hascode.tutorial.jee6.blog.entity.BlogEntry</class>
    		<properties>
    			<property name="eclipselink.ddl-generation" value="create-tables" />
    		</properties>
    	</persistence-unit>
    </persistence>

Validation using Bean Validation / JSR-303

Now that we have defined our entities and persistence unit we should add some validation rules not to allow to save invalid blog entries.

For a closer look and more detailed information about bean validation and jsr-303 take a look at my article: “Bean Validation with JSR-303 and Hibernate Validator

The rules that we’re going to define are ..

  • The title must not be null and its length must be between 10 and 100 characters
  • The content must not be null and its length must be between 300 and 4000 characters
  • The author must not be null and its length must be between 10 and 40 characters
  • The creation date, created should lie in the past
  • Applying some annotations from the bean validation API like @NotNull, @Size, @Past our BlogEntry’s fields look like this
    package com.hascode.tutorial.jee6.blog.entity;
     
    import java.io.Serializable;
    import java.util.Date;
     
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Lob;
    import javax.persistence.PrePersist;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Past;
    import javax.validation.constraints.Size;
     
    @Entity
    public class BlogEntry implements Serializable {
    	private static final long	serialVersionUID	= 1L;
     
    	@Id
    	@GeneratedValue
    	private Long				id;
     
    	@NotNull
    	@Size(min = 10, max = 100)
    	private String				title;
     
    	@Lob
    	@NotNull
    	@Size(min = 300, max = 4000)
    	private String				content;
     
    	@NotNull
    	@Size(min = 10, max = 40)
    	private String				author;
     
    	@Past
    	@Temporal(TemporalType.TIMESTAMP)
    	private Date				created = new Date();
     
    	@PrePersist
    	private void onCreate() {
    		created = new Date();
    	}
     
    	/**
    	 * @param id
    	 *            the id to set
    	 */
    	public void setId(Long id) {
    		this.id = id;
    	}
     
    	/**
    	 * @return the title
    	 */
    	public String getTitle() {
    		return title;
    	}
     
    	/**
    	 * @param title
    	 *            the title to set
    	 */
    	public void setTitle(String title) {
    		this.title = title;
    	}
     
    	/**
    	 * @return the content
    	 */
    	public String getContent() {
    		return content;
    	}
     
    	/**
    	 * @param content
    	 *            the content to set
    	 */
    	public void setContent(String content) {
    		this.content = content;
    	}
     
    	/**
    	 * @return the author
    	 */
    	public String getAuthor() {
    		return author;
    	}
     
    	/**
    	 * @param author
    	 *            the author to set
    	 */
    	public void setAuthor(String author) {
    		this.author = author;
    	}
     
    	/**
    	 * @return the created
    	 */
    	public Date getCreated() {
    		return created;
    	}
     
    	/**
    	 * @param created
    	 *            the created to set
    	 */
    	public void setCreated(Date created) {
    		this.created = created;
    	}
     
    	/**
    	 * @return the id
    	 */
    	public Long getId() {
    		return id;
    	}
    }

The middle tier using Enterprise Java Beans / EJB 3.1 – JSR-318

We’re going to use a stateless session bean to provide methods to save, delete and list our blog entry entities. We don’t define any local or remote interfaces to keep it simple here.

  • Create a new package named com.hascode.tutorial.jee6.blog.ejb and a class named BlogEntryEJB
    package com.hascode.tutorial.jee6.blog.ejb;
     
    import java.util.ArrayList;
    import java.util.List;
     
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
     
    import com.hascode.tutorial.jee6.blog.entity.BlogEntry;
     
    @Stateless
    public class BlogEntryEJB {
    	@PersistenceContext(unitName = "defaultPersistenceUnit")
    	private EntityManager	em;
     
    	public BlogEntry saveBlogEntry(BlogEntry blogEntry) {
    		em.persist(blogEntry);
    		return blogEntry;
    	}
     
    	public List<BlogEntry> findBlogEntries() {
    		final Query query = em.createQuery("SELECT b FROM BlogEntry b ORDER BY b.created DESC");
    		List<BlogEntry> entries = query.getResultList();
    		if (entries == null) {
    			entries = new ArrayList<BlogEntry>();
    		}
    		return entries;
    	}
     
    	public void deleteBlogEntry(BlogEntry blogEntry) {
    		blogEntry = em.merge(blogEntry);
    		em.remove(blogEntry);
    	}
    }
  • The unit name that we’re using in @PersistenceContext should  correspond to the defined named in our persistence.xml

Creating the presentation layer using Java Server Faces 2 and PrimeFaces

First we’re creating some facelets and decorators .. to keep this example simple we’re only creating a view to create new blog entries and a view that lists existing entries.

  • First we’re creating a decorator template named _decorator.xhtml in src/main/webapp
  • There are three fields in the decorator that may be overridden by our concrete views: the title, the heading and the body:
    <!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:h="http://java.sun.com/jsf/html"
    	xmlns:f="http://java.sun.com/jsf/core"
    	xmlns:ui="http://java.sun.com/jsf/facelets"
    	xmlns:p="http://primefaces.org/ui">
    <h:head>
    	<title><ui:insert name="title">hasCode.com - Java EE 6 Blog Tutorial</ui:insert></title>
    	<link rel="stylesheet" type="text/css" href="css/style.css" />
    </h:head>
    <h:body>
    	<p:panel>
    		<h:panelGrid columns="2" cellpadding="10">
    			<img src="image/logo.png" width="100" height="100" alt="hasCode.com logo"/>
    			<h:panelGroup>
    				<h1><ui:insert name="heading">Java EE 6 Tutorial - Blog Application</ui:insert></h1>
    			</h:panelGroup>
    		</h:panelGrid>
    		<ui:insert name="body">Welcome to the tutorial .. you should never see this content ;)</ui:insert>
    	</p:panel>
    </h:body>
    </html>
  • The ugly logo image is saved in src/main/webapp/image, the cascading stylesheets in src/main/webapp/css - this is my style.css
    h1 {
     font-size: 34px;
    }
    .errorMsg {
     background-color:#D97C7C;
     color:#A30000;
     display:block;
     padding:5px;
    }
  • Now we want to display available blog entries this is my view list.xhtml
    <!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:h="http://java.sun.com/jsf/html"
    	xmlns:f="http://java.sun.com/jsf/core"
    	xmlns:ui="http://java.sun.com/jsf/facelets"
    	xmlns:p="http://primefaces.org/ui">
    <ui:composition template="/_decorator.xhtml">
    	<ui:define name="title">
    		<h:outputText value="hasCode.com - Java EE 6 Blog Tutorial - Blog entries overview" />
    	</ui:define>
    	<ui:define name="heading">
    		<h:outputText value="Blog entries overview" />
    	</ui:define>
    	<ui:define name="body">
    		<h:form>
    			<h:commandButton title="Create new article"
    				value="Create new article" action="create" />
    			<br />
    			<hr />
    			<br />
    			<p:panel
    				header="#{blogEntryBean.getBlogEntries().size()} Blog entries available"
    				toggleable="true" closable="true" toggleSpeed="500">
    				<ui:repeat value="#{blogEntryBean.getBlogEntries()}" var="entry">
    					<h:panelGrid columns="2" cellpadding="10">
    						<f:facet name="header">
    							<h:outputText value="#{entry.title}" />
    						</f:facet>
    						<h:outputText value="Author: #{entry.author}" />
    						<h:panelGroup id="pGroup">
    							<h:outputText value="#{entry.content}" />
    							<p:contextMenu for="pGroup">
    								<p:menuitem value="Delete"
    									actionListener="#{blogEntryBean.delete(entry)}" update="@form" />
    							</p:contextMenu>
    						</h:panelGroup>
    						<f:facet name="footer">
    							<h:outputText value="Created: #{entry.created}" />
    						</f:facet>
    					</h:panelGrid>
    					<hr />
    				</ui:repeat>
    			</p:panel>
    		</h:form>
    	</ui:define>
    </ui:composition>
    </html>
  • We’re filling the decorator using ui:composition and ui:repeat to iterate over a list of available blog entries
  • PrimeFaces gives us nice panels and ajax-delete via context menu, nice is the @form expression that forces the form to update its content
  • We should adjust our web.xml in src/main/webapp/WEB-INF/ to load JSF and display list.xhtml per default
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     version="3.0"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
     <display-name>jee6-blog-tutorial</display-name>
     <servlet>
     <servlet-name>Faces Servlet</servlet-name>
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
     </servlet>
     <servlet-mapping>
     <servlet-name>Faces Servlet</servlet-name>
     <url-pattern>*.xhtml</url-pattern>
     </servlet-mapping>
     <welcome-file-list>
     <welcome-file>/list.xhtml</welcome-file>
     </welcome-file-list>
    </web-app>
  • Now we need a ManagedBean to link our views to the middle tier so we’re creating a class named BlogEntryBean in com.hascode.tutorial.jee6.blog.controller
    package com.hascode.tutorial.jee6.blog.controller;
     
    import java.util.List;
     
    import javax.enterprise.context.RequestScoped;
    import javax.inject.Inject;
    import javax.inject.Named;
     
    import com.hascode.tutorial.jee6.blog.ejb.BlogEntryEJB;
    import com.hascode.tutorial.jee6.blog.entity.BlogEntry;
     
    @Named(value = "blogEntryBean")
    @RequestScoped
    public class BlogEntryBean {
    	@Inject
    	private BlogEntryEJB	blogEntryEJB;
     
    	private BlogEntry		blogEntry	= new BlogEntry();
     
    	/**
    	 * @return the blogEntries
    	 */
    	public List<BlogEntry> getBlogEntries() {
    		return blogEntryEJB.findBlogEntries();
    	}
     
    	/**
    	 * @return the blogEntry
    	 */
    	public BlogEntry getBlogEntry() {
    		return blogEntry;
    	}
     
    	/**
    	 * @param blogEntry
    	 *            the blogEntry to set
    	 */
    	public void setBlogEntry(BlogEntry blogEntry) {
    		this.blogEntry = blogEntry;
    	}
     
    	public String saveBlogEntry() {
    		blogEntryEJB.saveBlogEntry(blogEntry);
    		return "success";
    	}
     
    	public void delete(BlogEntry blogEntry) {
    		blogEntryEJB.deleteBlogEntry(blogEntry);
    	}
    }
  • Please note that we’re using CDI for dependency injection here – that means @Named instead of @ManagedBean, @Inject instead of @EJB and javax.enterprise.context.RequestScoped instead of javax.faces.bean.RequestScoped!!
  • In the next step we should add some i18n and move our messages and text content to a resource bundle so create a directory src/main/resources/com/hascode/tutorial/jee6/blog and a new file named messages.properties in this directory.
    mkdir -p src/main/resources/com/hascode/tutorial/jee6/blog
  • Now we’ve got to register this resource bundle – we’re doing this via declaration in the JSF configuration file. Create a new file named faces-config.xml in src/main/webapp/WEB-INF and declare the resource bundle – in this case we’ve registered the bundle for variable named i18n
    <?xml version="1.0" encoding="UTF-8"?>
    <faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xi="http://www.w3.org/2001/XInclude" 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">
    	<application>
    		<resource-bundle>
    			<base-name>com.hascode.tutorial.jee6.blog.messages</base-name>
    			<var>i18n</var>
    		</resource-bundle>
    	</application>
    </faces-config>
  • Now we’re able to replace our messages via
    #{i18n.thekeyfromthebundle}
  • Finally out messages.properties looks like this
    listTitle=hasCode.com - Java EE 6 Blog Tutorial - Blog entries overview
    listHeading=Blog entries overview
  • Our update facelet list.xhtml now 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:h="http://java.sun.com/jsf/html"
    	xmlns:f="http://java.sun.com/jsf/core"
    	xmlns:ui="http://java.sun.com/jsf/facelets"
    	xmlns:p="http://primefaces.org/ui">
    <ui:composition template="/_decorator.xhtml">
    	<ui:define name="title">
    		<h:outputText value="#{i18n.listTitle}" />
    	</ui:define>
    	<ui:define name="heading">
    		<h:outputText value="#{i18n.listHeading}" />
    	</ui:define>
    	<ui:define name="body">
    		<h:form>
    			<h:commandButton title="#{i18n.newArticle}"
    				value="#{i18n.newArticle}" action="create" />
    			<br />
    			<hr />
    			<br />
    			<p:panel
    				header="#{blogEntryBean.getBlogEntries().size()} #{i18n.amountEntries}"
    				toggleable="true" closable="true" toggleSpeed="500">
    				<ui:repeat value="#{blogEntryBean.getBlogEntries()}" var="entry">
    					<h:panelGrid columns="2" cellpadding="10">
    						<f:facet name="header">
    							<h:outputText value="#{entry.title}" />
    						</f:facet>
    						<h:outputText value="#{i18n.author}: #{entry.author}" />
    						<h:panelGroup id="pGroup">
    							<h:outputText value="#{entry.content}" />
    							<p:contextMenu for="pGroup">
    								<p:menuitem value="#{i18n.delete}"
    									actionListener="#{blogEntryBean.delete(entry)}" update="@form" />
    							</p:contextMenu>
    						</h:panelGroup>
    						<f:facet name="footer">
    							<h:outputText value="#{i18n.created}: #{entry.created}" />
    						</f:facet>
    					</h:panelGrid>
    					<hr />
    				</ui:repeat>
    			</p:panel>
    		</h:form>
    	</ui:define>
    </ui:composition>
    </html>

Adding JSF Navigation Rules

We could have managed our user actions completely using nice PrimeFaces AJAX-enriched components or JSF’s native AJAX API but to demonstrate JSF’s navigation rules we’re going to define a new view with a form to create a new blog entry. If the blog entry has been successfully saved using this form we want to redirect our user to the entries-list-overview and the URL should change to avoid posting duplicate content by refreshing in the browser.

  • First we’re creating the new view reusing our decorator .. add a new template named create.xhtml in src/main/webapp
    <!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:h="http://java.sun.com/jsf/html"
    	xmlns:f="http://java.sun.com/jsf/core"
    	xmlns:ui="http://java.sun.com/jsf/facelets"
    	xmlns:p="http://primefaces.org/ui">
    <ui:composition template="/_decorator.xhtml">
    	<ui:define name="title">#{i18n.createTitle}</ui:define>
    	<ui:define name="heading">#{i18n.createHeading}</ui:define>
    	<ui:define name="body">
    		<h:form>
    			<p:panel id="createPnl" header="#{i18n.newArticle}"
    				toggleable="true" closable="false" toggleSpeed="500"
    				onCloseUpdate="growl" closeSpeed="2000" onToggleUpdate="growl"
    				widgetVar="panel">
    				<h:panelGrid columns="3" cellpadding="10">
    					<label>#{i18n.title}</label>
    					<h:inputText label="Title" id="lblTitle"
    						value="#{blogEntryBean.blogEntry.title}" required="true" />
    					<h:message for="lblTitle" class="errorMsg"/>
    					<label>#{i18n.author}</label>
    					<h:inputText label="Author" id="lblAuthor"
    						value="#{blogEntryBean.blogEntry.author}" required="true" />
    					<h:message for="lblAuthor" class="errorMsg"/>
    					<label>#{i18n.content}</label>
    					<h:inputTextarea label="Content" id="lblContent"
    						value="#{blogEntryBean.blogEntry.content}" required="true" />
    					<h:message for="lblContent" class="errorMsg"/>
    					<h:commandButton title="#{i18n.save}" value="#{i18n.save}"
    						action="#{blogEntryBean.saveBlogEntry()}" />
    				</h:panelGrid>
    			</p:panel>
    		</h:form>
    	</ui:define>
    </ui:composition>
    </html>
  • We need to update our internationalized messages in our messages.properties
    listTitle=hasCode.com - Java EE 6 Blog Tutorial - Blog entries overview
    listHeading=Blog entries overview
    newArticle=Create new blog entry
    amountEntries=Blog entries available
    author=Author
    options=Options
    delete=Delete
    created=Created
    createTitle=hasCode.com - Java EE 6 Blog Tutorial - Create a new blog entry
    createHeading=Create a new blog entry
    title=Title
    content=Content
    save=Save article
  • Add navigation rules to your faces-config.xml in src/main/webapp/WEB-INF .. mine now looks like this one
    <?xml version="1.0" encoding="UTF-8"?>
    <faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xi="http://www.w3.org/2001/XInclude" 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">
    	<application>
    		<resource-bundle>
    			<base-name>com.hascode.tutorial.jee6.blog.messages</base-name>
    			<var>i18n</var>
    		</resource-bundle>
    	</application>
     
    	<navigation-rule>
    		<from-view-id>/list.xhtml</from-view-id>
    		<navigation-case>
    			<from-outcome>create</from-outcome>
    			<to-view-id>/create.xhtml</to-view-id>
    		</navigation-case>
    	</navigation-rule>
    	<navigation-rule>
    		<from-view-id>/create.xhtml</from-view-id>
    		<navigation-case>
    			<from-outcome>success</from-outcome>
    			<to-view-id>/list.xhtml</to-view-id>
    			<redirect/>
    		</navigation-case>
    	</navigation-rule>
    </faces-config>
  • The redirect-Tag in the navigation-case forces the a redirect to list.xhtml

GlassFish Configuration

The GlassFish setup is quite easy we simply need a new domain and the embedded database because we’re too lazy to connect or create an external database ..

  • Start the GlassFish console via
    asadmin
  • Create a new domain named blog-domain
    asadmin> create-domain blog-domain
    Enter admin user name [Enter to accept default "admin" / no password]>
    Using port 4848 for Admin.
    Using default port 8080 for HTTP Instance.
    Using default port 7676 for JMS.
    Using default port 3700 for IIOP.
    Using default port 8181 for HTTP_SSL.
    Using default port 3820 for IIOP_SSL.
    Using default port 3920 for IIOP_MUTUALAUTH.
    Using default port 8686 for JMX_ADMIN.
    Using default port 6666 for OSGI_SHELL.
    Distinguished Name of the self-signed X.509 Server Certificate is:
    [CN=yourworkstationname,OU=GlassFish,O=Oracle Corporation,L=Santa Clara,ST=California,C=US]
    No domain initializers found, bypassing customization step
    Domain blog-domain created.
    Domain blog-domain admin port is 4848.
    Domain blog-domain allows admin login as user "admin" with no password.
    Command create-domain executed successfully.
  • Start the created domain
    asadmin> start-domain blog-domain
    Waiting for DAS to start .................................
    Started domain: blog-domain
    Domain location: /somepath/app/glassfishv3/glassfish/domains/blog-domain
    Log file: /somepath/app/glassfishv3/glassfish/domains/blog-domain/logs/server.log
    Admin port for the domain: 4848
    Command start-domain executed successfully.
  • Start the embedded Derby/JavaDB database
    asadmin> start-database
    Starting database in Network Server mode on host 0.0.0.0 and port 1527.
    [..]
    ------------------------------------------------------
    Starting database in the background.
    Log redirected to /somepath/derby.log.
    Command start-database executed successfully.
  • Visit the administration console in your browser at http://localhost:4848/ and enjoy ;)

Deploying and Running the Application

  • First build the war file for deployment using
    mvn package
  • Ensure that your GlassFish server is running, the database is started and the domain “blog-domain” is created and started
  • Log into the GlassFish administration console at http://localhost:4848/ with login “admin” and empty password if you haven’t defined one in the domain creation process
  • Click on “Applications” and deploy the application via file upload as shown as in the following screenshots

    GlassFish Application Deployment Step 1

    GlassFish Application Deployment Step 1

    GlassFish Application Deployment Step 2

    GlassFish Application Deployment Step 2

    GlassFish Application Deployment Step 3

    GlassFish Application Deployment Step 3

    GlassFish Application Deployment Step 4

    GlassFish Application Deployment Step 4

  • Now click on “Launch” and visit your application at this location: http://localhost:8080/blog-tutorial

    View as screencast on YouTube

Download Sources

The sources for this tutorial are available on my Bitbucket repository  .. download it from here or check it out using

hg clone https://hascode@bitbucket.org/hascode/javaee6-blog-tutorial

Troubleshooting

  • Exception while preparing the app : org.hibernate.AnnotationException: No identifier missing @Id attribute“: You’ve forgotten to specify an identifying property for your entity class .. e.g.: @Id private Long id;
  • Exception [EclipseLink-4002] (Eclipse Persistence Services – 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLNonTransientConnectionException: No current connection. java.sql.SQLNonTransientConnectionException: No current connection. org.apache.derby.client.am.SqlException: No current connection.“: In this tutorial we’re lazy and rely on GlassFish’s embedded database. To use this database it must be started first as this
    asadmin
    asadmin> start-database
    Starting database in Network Server mode on host 0.0.0.0 and port 1527.
  • [#|2011-01-16T17:47:47.364+0100|WARNING|glassfish3.0.1|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=30;_ThreadName=Thread-1;|StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception javax.el.PropertyNotFoundException or: CDI does not work somehow“: You need to put an empty text file named beans.xml in src/main/webapp/WEB-INF – strange but necessary ;) For more information take a look at Gavin King’s blog article: “Why is beans.xml required in CDI?
  • Caused by: java.lang.IllegalArgumentException: Entity must be managed to call remove: com.hascode.tutorial.jee6.blog.entity.BlogEntry@184340e, try merging the detached and try the remove again. at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.performRemove(UnitOfWorkImpl.java:3539)“: This is the standard detached object problem .. in JPA there are four possible object states .. new, removed, managed and of course detached .. the last one has a persistent identity that no longer is associated with a persistence context. EntityManager’s merge method is what helps you to “reattach” the bean .. look at this sample code
    public void theMethod(XXX entityBean) {
     entityBean = em.merge(entityBean);
     em.remove(entityBean);
    }
  • PrimeFaces is not defined“: There was an issue with some menu components in PrimeFaces 2.2.RC1, Cagatay Civici has already fixed this one in version 2.2.RC2 and above.
  • Duplicate menuitem in contextmenu“: Again Cagatay Civici saved the day and fixed this issue, update to version 2.2-SNAPSHOT or above.
  • Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-dependency-plugin:2.1:copy (execution: default, phase: validate)” – It’s the m2eclipse plugin .. why does this error occur? They’re explaining it in this article .. for now add the following code to your pom.xml and update your project configuration
    <pluginManagement>
    	<plugins>
    		<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
    		<plugin>
    			<groupId>org.eclipse.m2e</groupId>
    			<artifactId>lifecycle-mapping</artifactId>
    			<version>1.0.0</version>
    			<configuration>
    				<lifecycleMappingMetadata>
    				<pluginExecutions>
    					<pluginExecution>
    						<pluginExecutionFilter>
    							<groupId>org.apache.maven.plugins</groupId>
    							<artifactId>maven-dependency-plugin</artifactId>
    							<versionRange>[2.1,)</versionRange>
    							<goals>
    								<goal>copy</goal>
    							</goals>
    						</pluginExecutionFilter>
    						<action>
    							<ignore></ignore>
    						</action>
    					</pluginExecution>
    				</pluginExecutions>
    				</lifecycleMappingMetadata>
    			</configuration>
    		</plugin>
    	</plugins>
    </pluginManagement>

Resources

Additional Articles: Testing with Arquillian

If you’re interested in testing your Java EE application , please feel free to have a look at the following tutorials of mine covering the Arquillian framework:

Article Updates

  • 2018-06-01: Embedded YouTube video removed (GDPR/DSGVO).
  • 2015-03-21: Links to my Arquillian articles added, formatting fixed.

Tags: , , , , , , , , , , , , , , , , , , , , , , , ,

85 Responses to “Creating a sample Java EE 6 Blog Application with JPA, EJB, CDI, JSF and Primefaces on GlassFish”

  1. Barry van Someren Says:

    Simple, to the point and complete.
    Good job on the tutorial :)

  2. Bruce Phillips Says:

    Excellent tutorial. I followed along building the application in Eclipse with GlassFish v3 as the server and everything worked perfectly.

    Just a couple of question…

    1. Is EclipseLink/TopLink built-in to GlassFish v3? I don’t see it listed in the pom’s dependencies.

    2. What’s the purpose of endorseddirs in your pom.xml? Is that needed to build this application? I’ve not seen endorseddirs before in Java EE 6 app’s pom.xml.

  3. micha kops Says:

    Thanks for your post :)

    1) EclipseLink is GlassFish’s default persistence provider, earlier versions (<3.0.1) TopLink Essentials (http://download.oracle.com/docs/cd/E19798-01/821-1762/gjizi/index.html)

    2) You don't need the endorsed dirs to build this tutorial .. basically the maven settings above add this function: a) the maven dependency plugin copies javaee-endorsed-api-6.0.jar to the directory target/endorsed b) the compiler adds this directory as endorseddir to override/extend jdk functions (http://download.oracle.com/javase/6/docs/technotes/guides/standards/)

  4. audrey Says:

    Thank you for the tutorial.
    I’ve just completed and it works.
    I personally learned a lot from it. I still need to review some concepts, but thank you for a complete tutorial.

  5. jmarranz Says:

    PrimeFaces p:contextMenu doesn’t work for me (nothing is shown)

  6. jmarranz Says:

    Sorry, It works fine, I forgot it works by clicking the right button.

  7. micha kops Says:

    I’m glad to hear that :)

  8. Review HandsOn JSF 2.0 | Donato Info Says:

    [...] Imagem retirada de: http://www.hascode.com/2011/02/creating-a-sample-java-ee-6-blog-application-with-jpa-ejb-cdi-jsf-and... [...]

  9. chuong Says:

    Wonderful, no-nonsense tutorial, Micha. Thanks. Your tutorial is the best so far on the Internet.

    Also, I’m using Apache OpenJPA 2.1.0 and I have included this file “openjpa-all-2.1.0.jar” in my Eclipse project but the following imported libraries cannot be resolved:
    1) javax.ejb.Stateless;
    2) import javax.enterprise.context.RequestScoped;
    3) import javax.inject.Inject;
    4) import javax.inject.Named;

    Is this an issue only with OpenJPA and not EclipseLink? What can I do to resolve the missing libraries? Please help.

  10. micha kops Says:

    Those dependencies are all covered by the artifact javaee-web-api:

    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>6.0</version>
      <scope>provided</scope>
    </dependency>
    

    However If you’re trying to build without Maven, just download the Jar from the Maven repository and add it as an external jar to your project:
    http://download.java.net/maven/2/javax/javaee-web-api/6.0/javaee-web-api-6.0.jar

  11. chuong Says:

    Thanks, Micha. Much appreciated. You save me a couple of hours floundering on Google trying to find the right library for the unresolved classes.

    Also, can I do something like this if I pass a parameter to a query in the EJB class:

    final Query query = em.createNamedQuery(“findBlogEntry”).setParameter(“blogId”, blogid).getResultList();

    Where findBlogEntry is defined in the Entity class as:

    @Entity
    @NamedQuery({
    @NamedQuery(name = “findBlogEntry”, query = “SELECT b.* FROM BlogEntry b WHERE b.blogId = :id”});

    Sorry for asking a dumb question but I find the EJB + JPA stuff very hard to understand and my understanding is further complicated by coming across something like this:

    http://soadev.blogspot.com/2010/02/dynamic-tree-menu-based-on-user-roles.html

    Is this another way one can configure EJB + Entity for CRUD operation? Or, is this a BAD (and possibly, not recommended) way of doing it? Can you please confirm. Thank you.

  12. micha kops Says:

    You should be able to use named or enumerated parameters on JPA entity’s named queries + queries .. perhaps this other article of mine is of help for you: “Object-relational Mapping using Java Persistence API / JPA 2

  13. chuong Says:

    Thanks, Micha. That article make sense and it answers my question above about NameQuery/NameQueries defined in Entity class.

  14. Chuong Says:

    Tried the above codes – everything good – except that this EL expression blogEntryBean.getBlogEntries() in list.xhtml will be executed 6 times for each phase of the JSF lifecycle.

  15. chuong Says:

    The above demo works great except that blogEntryBean.getBlogEntries() in list.xhtml will be called 6 times for each phase of the JSF lifecycle.

  16. micha kops Says:

    I’m not sure why the method is called six times in your environment – in mine it is called two times .. one time for the display of the number of available entries and one time for the iteration loop (this is of course no ideal layout but sufficient for a quick tutorial :)

  17. chuong Says:

    Yeah, I’m not sure either!

    Debugging the codes revealed that the method got called 6 times – which to my knowledge – corresponded to the phases of the JSF lifecycle. I tried both blogEntryBean.getBlogEntries() and blogEntryBean.blogEntries and I got the same result.

    Anyway, I’ll investigate a bit more and see what I can find…

  18. Zotona Says:

    Hi from Russia! Thanks for great tutorial!
    But one question, because i cant find it by google. How can i use JSF with JAX-WS client?
    i want to display a table by jsf. In JAX-ws class i have a method “findall” and “find”, what returns all data and other one entry. Please tell me in common words what i must do. Thanks!!!

  19. micha kops Says:

    You could pass the list of items received to a backing bean and then render it in a table using ui:repeat or a data table component of your choice .. PrimeFaces’ DataTable components has some nice features and is definitely worth a look

  20. Radu Says:

    Nice tutorial, however some missing points make it hard to adapt for a real application.

    First, you should add a count() method to BlogEntryEJB and BlogEntryBean.
    Using blogEntryBean.getBlogEntries().size() will read ALL blog entries from database, which is not what you want.

    What could make a difference from all other JSF CRUD tutorials is adding pagination support on the server side. While this is one of the most important aspect of a CRUD application, it can be quite a challenger to achieve in JSF application without using @SessionScoped beans – using flash scope parameters, page parameters and post-redirect-get.

    Even NetBeans CRUD page generation wizard is not usable.

    Otherwise, nice explanations and screenshots!

  21. unkis Says:

    Nice tutorial, however i got the folowing exception:
    javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:’prePersist’. Please refer to embedded ConstraintViolations for details.
    at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.validateOnCallbackEvent(BeanValidationListener.java:90)
    at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.prePersist(BeanValidationListener.java:62)
    at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:698)
    at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:641)
    at org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:200)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectClone(UnitOfWorkImpl.java:4216)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNotRegisteredNewObjectForPersist(UnitOfWorkImpl.java:4193)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.registerNotRegisteredNewObjectForPersist(RepeatableWriteUnitOfWork.java:493)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4135)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:406)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:269)
    at com.hascode.tutorial.jee6.blog.ejb.BlogEntryEJB.saveBlogEntry(BlogEntryEJB.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5367)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:801)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
    at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:46)
    at sun.reflect.GeneratedMethodAccessor111.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:862)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:801)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
    at sun.reflect.GeneratedMethodAccessor110.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:862)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:801)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:371)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5339)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5327)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
    … 62 more

  22. john Says:

    > While this is one of the most important aspect of a CRUD application, it can be quite a challenger to achieve in JSF application without using @SessionScoped beans – using flash scope parameters, page parameters and post-redirect-get.

    @ViewScoped is the most natural fit here.

  23. Thobela Says:

    a very good intro indeed, you are a star

  24. Amar Pandav Says:

    Hi Micha,
    Thanks alot for this quick start. I followed all steps but my eclipse Indigo is giving me error as -
    Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-dependency-plugin:2.1:copy (execution: default, phase: validate)

    where as mvn clean install gave me below error -
    [ERROR] Failed to execute goal on project jee6-blog-tutorial: Could not resolve dependencies for project com.hascode.tutorial.jee6:jee6-blog
    -tutorial:war:0.0.1: Failed to collect dependencies for [javax:javaee-web-api:jar:6.0 (compile), javax.validation:validation-api:jar:1.0.0.G
    A (provided), org.hibernate:hibernate-validator:jar:4.0.2.GA (compile), junit:junit:jar:4.8.2 (test), org.apache.derby:derby:jar:10.6.1.0 (c
    ompile), org.primefaces:primefaces:jar:2.2 (compile), javax.faces:jsf-api:jar:2.0 (provided)]: Failed to read artifact descriptor for org.pr
    imefaces:primefaces:jar:2.2: Could not transfer artifact org.primefaces:primefaces:pom:2.2 from/to JBoss repository (http://repository.jboss
    .com/maven2/): Access denied to: http://repository.jboss.com/maven2/org/primefaces/primefaces/2.2/primefaces-2.2.pom -> [Help 1]

  25. Amar Pandav Says:

    Hi Micha,
    Second problem is fixed.
    The problem was – Primefaces has changed its repo –
    http://blog.primefaces.org/?p=1429
    Pls update this tutorial.

    But still problem 1 regarding Plugin execution, persist.

  26. micha kops Says:

    Hi Amar,

    thanks for your note – I have updated the location of the primefaces maven repo to the new address.

    The lifecycle error is one of the “features” of the new Sonatype m2eclipse Plugin – they’ve written this article to explain why this problem exists.
    One workaround is to make the m2eclipse plugin ignore the unknown lifecycle by adding the following snippet to your pom.xml’s build element (m2eclipse offers this solution if you’re opening the pom.xml in the pom editor):
    <pluginManagement>
    <plugins>
    <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
    <plugin>
    <groupId>org.eclipse.m2e</groupId>
    <artifactId>lifecycle-mapping</artifactId>
    <version>1.0.0</version>
    <configuration>
    <lifecycleMappingMetadata>
    <pluginExecutions>
    <pluginExecution>
    <pluginExecutionFilter>
    <groupId>
    org.apache.maven.plugins
    </groupId>
    <artifactId>
    maven-dependency-plugin
    </artifactId>
    <versionRange>
    [2.1,)
    </versionRange>
    <goals>
    <goal>copy</goal>
    </goals>
    </pluginExecutionFilter>
    <action>
    <ignore></ignore>
    </action>
    </pluginExecution>
    </pluginExecutions>
    </lifecycleMappingMetadata>
    </configuration>
    </plugin>
    </plugins>
    </pluginManagement>

    Afterwards you should be able to compile the application without any problems ..

  27. Amar Pandav Says:

    Thanks Micha the plugin problem is fixed.

    The tutorial helped me alot to kick start me.

    One thing would be really nice if you could help me -
    Here you explained to use external glassfish. Is there a way to use the glassfish from eclipse itself and it does every thing for me. With this it will re-deploy all changes immediately.

  28. Amar Pandav Says:

    Hi Micha, One more thing, I am not able to download sources for javax javaee-web-api 6.0?

  29. micha kops Says:

    One way is to use the GlassFish Maven Plugin as described in this article or to make convert your project to a facet project, add the ejb facet, add a glassfish server and use run on server

  30. micha kops Says:

    isn’t it present on http://download.java.net/maven/2/javax/javaee-web-api/6.0/ ? :)

  31. Amar Pandav Says:

    Hi Micha,
    No the sources are not present there.

  32. micha kops Says:

    ah the sources .. I havent found a repository for this one yet so a possible (annoying) workaround is to download the sources from here and run something like this mvn install:install-file -Dfile=javadoc-6.0.1.jar -DgroupId=javax -DartifactId=javaee-web-api -Dversion=6.0 -Dpackaging=jar -Dclassifier=javadoc .. the project might be re-imported afterwards depending on the eclipse/maven plugin used ..

    There’s an issue regarding this problem (open since October 2010) .. you might want to vote on this one :) #GLASSFISH-11389

  33. arun Says:

    Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.IllegalArgumentException: javax.servlet.ServletException: com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class org.jboss.weld.servlet.WeldListener. Please see server.log for more details.

  34. _jas Says:

    hi, awsome tutorial for a jee6 starter.
    Almost got it working, the only problem, it’s that after pressing save button, get this:

    javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:’prePersist’. Please refer to embedded ConstraintViolations for details.

    After searching a lot, i couldn’t solve it. if you got any idea i’ll really apreciate that.

    late ;D

  35. micha kops Says:

    thanks! do you have some more information – e.g. a more detailed stack trace? have you modified the code from the tutorial somehow .. e.g. mixed @NotNull and @Id or something like that? You might try to catch the exception and call getConstraintViolations() on it to find out which constraints were violated.
    I’ve tested the tutorial code against the latest GlassFish version just to be sure it works.

  36. _jas Says:

    sorry about the stack trace, just a noob in glassfish, that’s why i just put that :p

    about annotations: i changed stuff but only packages, and i18n stuff. not touched the entity anotations.

    i followed your advice and catched the exception, and got a surprise…
    the values of the object where null. almost all of them, except for the time stamp.

    going backwards, found that the values are never getting in the JSF bean.
    So when it arrives to the ejb, is empty.

    still trying to figure out what can be that make that behavior. guess i’m missing something about the @Named stuff. ( i had put the empty beans.xml )
    when its solved i’ll let you know ;D
    thnx for the help.

  37. _jas Says:

    nevermind. my mistake there was that had imported the wrong annotation.
    ( i’ve done the project step by step, without donwloading, thats why i have some mistakes about imports.i guess the eclipse import and not paying much attention on that )

    conclusion:
    @named > @request ( the enterprise context request, not the faces context).

    after that i got an error on the @past, cannot solve it so removing it it worked fine.

    thnx again for such a great introduction.

  38. micha kops Says:

    I’m glad to hear that it worked for you – and thanks for keeping me updated :)

  39. _jas Says:

    in case someone wants to update this projecto to last version of primefaces (3.2 nowadays )
    when creating the xhtml, in the html tag, put this:

    xmlns:p=”http://primefaces.org/ui”

    instead of

    xmlns:p=”http://primefaces.prime.com.tr/ui”

    may be updating this tutorial will be nice :).
    ( and may be add a DB server, not embebed ( mysql or something. )
    late ;D

  40. micha kops Says:

    thanks for mentioning! in my latest tutorials (primefaces mobile etc ..) I’m already using the new namespace .. I could update the tutorial to use the latest versions of the major frameworks used one day indeed

  41. mlb1141 Says:

    Great. This is a very informative tutorial. I do have one question however. I have noticed many tutorials where they use dependency injection to inject an entity (BlogEntry) into the controller/backing bean. Does this violate separation of concerns? Is it just the responsibility of the programmer to use the entity in the controller in a way that does not violate separation of concerns or am I just totally confused. Thanks.

  42. Youssef Says:

    Hi micha
    i have a problem and i’m tired to resolve it
    help plz !!

    when i try to deploy blog-tutorial on glassfish server
    i have this error :
    StandardWrapperValve[FacesServlet]: PWC1406: Servlet.service() for servlet FacesServlet threw exception java.lang.ClassNotFoundException: org.apache.commons.io.output.DeferredFileOutputStream at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) at org.apache.commons.fileupload.DefaultFileItemFactory.createItem(DefaultFileItemFactory.java:103) at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:358) at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:310) at com.sun.webui.jsf.util.UploadFilter.doFilter(UploadFilter.java:176) at

    if you have any idea
    Thanks

  43. micha kops Says:

    Hi, sorry to hear that .. which glassfish version are you using here? you’re just building the blog application with maven, you’re uploading it in the glassfish web adminstration panel as a web application and this exception is thrown?

  44. Youssef Says:

    yes this is what’s happened
    i’m using glassfish-3.1.2, i verified all my sources compared with your code as well, everything is Ok

  45. hamza Says:

    i have a problem
    after execute my project
    type Exception report

    message

    descriptionThe server encountered an internal error () that prevented it from fulfilling this request.

    exception

    javax.servlet.ServletException

    root cause

    javax.ejb.EJBException

    root cause

    java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName defaultPersistenceUnit

  46. micha kops Says:

    Hi, is this persistence unit defined in your persistence.xml? and does the jta datasource named “jdbc/__default” exist on your GlassFish configuration?

  47. hamza Says:

    hi,micha
    jdbc/__default exist on my glassFish configuration
    but i didn’t understand what is the problem exactly

  48. micha kops Says:

    hi hamza,

    did you start the embedded database via “asadmin” and “start-database”?

  49. serge Says:

    Youssef: works for me on gf 3.1.2 .. your problem sounds like a gf problem for me .. any special configuration here?

  50. hamza Says:

    Erreur lors du déploiement : Exception while preparing the app : Exception [EclipseLink-4002] (Eclipse Persistence Services – 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Erreur lors de l’allocation d’une connexion. Cause : Connection could not be allocated because: java.net.ConnectException : l’erreur lors de la connexion au serveur localhost sur le port 1527 a émis le message Connection refused: connect. Error Code: 0. Pour plus d’informations, consultez le fichier server.log.

  51. hamza Says:

    hi micha
    i start the embedded database and i add the jar toplink in domaine/lib/ext in glassfish …
    but i have another exception after execution this project

    Exception while preparing the app : Exception [EclipseLink-4002] (Eclipse Persistence Services – 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Erreur lors de l’allocation d’une connexion. Cause : Connection could not be allocated because: java.net.ConnectException : l’erreur lors de la connexion au serveur localhost sur le port 1527 a émis le message Connection refused: connect.

    i need helps
    thanks

  52. micha kops Says:

    seems like you’re not able to connect to the database .. any hint in your database logs in /path/to/glassfish3-installation/glassfish/databases/derby.log? are you able to directly connect to the derby database using ij or another tool? is there something in your environment that blocks a connection – e.g. firewall or stuff like that?

  53. Youssef Says:

    Hi all,
    I have arrived to deploy the example and i’ts work fine, so i’m using JBOSS AS7 for this…

    Otherwise, i have another issue when i create blog, it concerne annotation @Past

    exception :

    avax.validation.ConstraintViolationException: Validation failed for classes [fr.rsi.foundation.tutoriel.jee6.blog.entity.BlogEntry] during persist time for groups [javax.validation.groups.Default, ]
    List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='must be in the past', propertyPath=created, rootBeanClass=class fr.rsi.foundation.tutoriel.jee6.blog.entity.BlogEntry, messageTemplate='{javax.validation.constraints.Past.message}'}
    ]
    org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:159)

    So, i don’t know why for the first time i created an article, i didn’t have this error !

    I think, the date created through “@PrePersist” when the Entity is loaded & the local date used when the entityManager try to persist the object are equivalent. but if it’s about a datetime it should have some difference of seconds

    any idea ?

  54. Joseph Says:

    Great tutorial. One question. You have shown how to perform CRD of CRUD. Can you show us how to do updates using JSF 2 + JPA?

    Thanks,
    Joseph

  55. mauro Says:

    i have try the tutorial with:
    glassfish 3.1.2.2
    jsf mojarra
    primefaces 3.4
    but into the create.xhtnl the it is not faound .
    you can helop me?
    the ajax event it is changed form primefaces 2.2
    .
    help me

  56. Banifou Says:

    Great! works fine on Glassfish 3.1.2.2! I’m gonna integrate it as a blog in my webapp , which works with primefaces already.

  57. Pablo Says:

    Great job man! Fantastic entry to refresh ideas.
    Thanks!
    Pablo

  58. Haris Persidis Says:

    Hello i did every step like you but i get an error

    The module has not been deployed.
    See the server log for details.
    BUILD FAILED (total time: 1 second)

  59. micha kops Says:

    Hi,

    could you post some more details about the error – e.g. an excerpt from your server.log?

  60. dalun Says:

    Hi,
    I need ur help. when i clicked on the “save article”, i had this error:
    javax.ejb.EJBTransactionRolledbackException: Transaction rolled back

  61. micha kops Says:

    Hi Dalun,

    could you please post the complete stack trace?

  62. dalun Says:

    hi,
    thank you, u can find it below:

    javax.faces.el.EvaluationException: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50)
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
    at java.lang.Thread.run(Thread.java:662)
    Caused by: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleEndTransactionException(CMTTxInterceptor.java:115)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:95)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:232)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:304)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:32)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:165)
    at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:173)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:72)
    at com.admin.data.BlogEntryEJB$$$view4.saveBlogEntry(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:264)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137)
    at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:260)
    at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:111)
    at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
    at com.admin.data.BlogEntryEJB$Proxy$_$$_Weld$Proxy$.saveBlogEntry(BlogEntryEJB$Proxy$_$$_Weld$Proxy$.java)
    at com.admin.controller.BlogEntryBean.saveBlogEntry(BlogEntryBean.java:34)
    at com.admin.controller.BlogEntryBean$Proxy$_$$_WeldClientProxy.saveBlogEntry(BlogEntryBean$Proxy$_$$_WeldClientProxy.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    … 25 more
    Caused by: javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
    at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1177)
    at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:117)
    at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:92)
    … 70 more
    Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Les Large Objects ne devraient pas être utilisés en mode auto-commit.
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295)
    at org.hibernate.ejb.AbstractEntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1481)
    at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:109)
    at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53)
    at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273)
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93)
    at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:164)
    at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1165)
    … 73 more
    Caused by: org.hibernate.exception.GenericJDBCException: Les Large Objects ne devraient pas être utilisés en mode auto-commit.
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:52)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at com.sun.proxy.$Proxy71.setClob(Unknown Source)
    at org.hibernate.type.descriptor.sql.ClobTypeDescriptor$2$1.doBind(ClobTypeDescriptor.java:69)
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300)
    at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:57)
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2593)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2846)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3290)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:80)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315)
    at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104)
    … 79 more
    Caused by: org.postgresql.util.PSQLException: Les Large Objects ne devraient pas être utilisés en mode auto-commit.
    at org.postgresql.largeobject.LargeObjectManager.createLO(LargeObjectManager.java:301)
    at org.postgresql.largeobject.LargeObjectManager.createLO(LargeObjectManager.java:288)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.setClob(AbstractJdbc2Statement.java:3180)
    at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.setClob(WrappedPreparedStatement.java:1102)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)

  63. dalun Says:

    i’m using JBoss as 7 server and maven3.

  64. dalun Says:

    its works well now! ijust removed @Lob in my entity class. thanks again!

  65. micha kops Says:

    I’m glad that it worked out for you – and thanks a lot for keeping me updated! :)

  66. Milan Says:

    I was using your tutorial to create my own PrimeFaces application (jboss 7, Eclipse) and I had some problems with components that were not rendered until I substituted xmlns:p=”http://primefaces.prime.com.tr/ui” with xmlns:p=”http://primefaces.org/ui”. Eclipse also started autocompleting the tags after the substitution.

  67. micha kops Says:

    Hi,

    thanks for your remark! The namespace has changed a few years ago and I’ve not updated all of my primefaces tutorials yet.

    Tutorial updated! :)

    Cheers,

    Micha

  68. nadjah Says:

    Hello Micha,

    Thank you so much for this very clear article.

    i followed all steps, but when i lunch it i have this problem :
    1/ when i lunch it from the glassfish editor, it gaves me this :
    “”
    If the server or listener is not running, the link may not work. In this event, check the status of the server instance. After launching the web application, use the browser’s Back button to return to this screen.”"

    2/ and when i tried to run it on server (run th create.xhtml page) i had this:

    descriptionThe server encountered an internal error () that prevented it from fulfilling this request.

    exception
    javax.servlet.ServletException: Can’t find bundle for base name /webapp-javaee6/src/blog/messages.properties, locale fr_FR

    root cause
    java.util.MissingResourceException: Can’t find bundle for base name /webapp-javaee6/src/blog/messages.properties, locale fr_FR

    The server encountered an internal error () that prevented it from fulfilling this request.

    can you help me with this please.

    Thank you so much.

    Nadjah :)

  69. nadjah Says:

    hello Micha,

    by chance i found the problem and i fixed it.

    i have another problem, the famous HTTP STATUS 404 => the requested resource in not available.

    i don’t know what to do, and i’m stuck, so can you please help me .

    thank you!!

    nadjah!

  70. micha kops Says:

    Hi Nadjah,

    I suppose you’ve added a property-file for french locale? :)

    To reproduce your problem: Did you create your own Java EE application in a similar way as in the tutorial? Or did you download the sources, built the project using Maven, configured the GlassFish and having deployed the war file you’re not able to open the application in your browser?

    Best wishes

    Micha

  71. nadjah Says:

    hi Micha,

    thank you for the answer :)

    =>yes, i added a property file for french local. (/webapp-javaee6/src/blog/messagesBundle-fr-FR.properties) (is the path right or not??)

    =>all my xhtml pages (create, list and decorator) are in the web content.

    i didn’t create the project on maven commadn,on eclipse i started by creating a dynamic project than i convert it to a maven project, after that i added the dependacies, than i deployed it on the glassfish, after creating a pool connexion and a data source. i checked every thing in the properties of the project and it seems that everything is ok.

    => i made some changes and now, i got this probleme :
    java.util.MissingResourceException: Can’t find bundle for base name webapp-javaee6.src.blog.messagesBundle-fr-FR.properties, locale fr_FR
    at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)
    at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)
    at java.util.ResourceBundle.getBundle(ResourceBundle.java:1028)
    at com.sun.faces.application.ApplicationResourceBundle.getResourceBundle(ApplicationResourceBundle.java:124)
    at com.sun.faces.application.ApplicationAssociate.getResourceBundle(ApplicationAssociate.java:608)
    at com.sun.faces.application.ApplicationImpl.getResourceBundle(ApplicationImpl.java:700)
    at javax.faces.application.ApplicationWrapper.getResourceBundle(ApplicationWrapper.java:526)
    at com.sun.faces.el.FacesResourceBundleELResolver.getValue(FacesResourceBundleELResolver.java:83)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
    at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    at javax.faces.component.UIOutput.getValue(UIOutput.java:169)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1764)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:744)

  72. micha kops Says:

    Hi Nadjah,

    you may specify the i18n settings for JSF in your faces-config like this:

    <application>
    <resource-bundle>
    <base-name>yourbundlebasename</base-name>
    <var>msg</var>
    </resource-bundle>
    <locale-config>
    <default-locale>en</default-locale>
    <supported-locale>fr</supported-locale>
    </locale-config>
    </application>

    For a comparison: This is the location of the resource-bundle properties file from my tutorial when I’m analyzing the generated war file:

    Hi Nadjah,

    you may specify the i18n settings for JSF in your faces-config like this:

    <application>
    <resource-bundle>
    <base-name>yourbundlebasename</base-name>
    <var>msg</var>
    </resource-bundle>
    <locale-config>
    <default-locale>en</default-locale>
    <supported-locale>fr</supported-locale>
    </locale-config>
    </application>

    For a comparison: This is the location of the resource-bundle properties file from my tutorial when I'm analyzing the generated war file:

    % tree -P messages.properties
    .
    ├── css
    ├── image
    ├── META-INF
    │   └── maven
    │       └── com.hascode.tutorial.jee6
    │           └── jee6-blog-tutorial
    └── WEB-INF
        ├── classes
        │   ├── com
        │   │   └── hascode
        │   │       └── tutorial
        │   │           └── jee6
        │   │               └── blog
        │   │                   ├── controller
        │   │                   ├── ejb
        │   │                   ├── entity
        │   │                   └── messages.properties
        │   └── META-INF
        └── lib
    

  73. nadjah Says:

    hello Micha,

    i finally found the solution, you were right concerning the faces-config, and the problem was in my web.xml

    the only thing that i found realy bizzare is that, when i lunch the project from glassfish, i don’t have directly the create.xhtml page, i have to clic on a link http://name-pc:8080/create.xhtml, and then i have the page!!!

    thank you for your help and your time.

    nadjah :)

  74. micha kops Says:

    Hi Nadjah,

    I’m glad to hear it’s working for you now. If you’d like to specify a view as start-page, you may do so by adding the following lines to your web.xml:

    <welcome-file-list>
    <welcome-file>/create.html</welcome-file>
    </welcome-file-list>

  75. nadjah Says:

    hello Micha,

    i realy appreciate the fact that you answer all my question, i have this last one (i sorry :().

    earlier, you told me to change my faces-confi with this :

    yourbundlebasename
    msg

    en
    fr

    and it worked.the question is:
    do i have to change in the create, list.xhtml pages the #i18n with msg??? when i try to do this it doesn’t work ?????

    => when i lunch the page i have the structure as in the video, but no title, and sub titles like (author, content). what can cause this problem.

    thank you so much for your help.

    PS: i’m not tht good in english, i’m doing my best :)

    nadjah

  76. micha kops Says:

    Hi Nadjah,

    et moi, je ne sais pas bien parler français :)

    You’re right indeed that you need to modify the variable name – this is the faces-config.xml excerpt from my application (using i18n as variable name):

    <application>
    <resource-bundle>
    <base-name>com.hascode.tutorial.jee6.blog.messages</base-name>
    <var>i18n</var>
    </resource-bundle>
    </application>

    If you can’t resolve the resouce bundle, please verify your war-file if it contains the properties file in the right place – as described above and with the base-name com.hascode.tutorial.jee6.blog.messages, my war file contains a file named messages.properties in WEB-INF/classes/com.hascode.tutorial.jee6.blog.

  77. Denford Says:

    Can never thank you enough. Thanks.

  78. micha kops Says:

    You’re welcome!

  79. Subhash Says:

    Hi Micha,
    Thank you for such a good example for the beginners. I have developed a multi module maven project based on your sample and now i am trying to add the logging for it, could you please try to tell me how to do it as i am unable to understand where to configure the properties file and so on.

    One more doubt in the existing project is that if i wanted to use the derby out side of the glass fish how should i do it.

    Thanks & Regards
    Subhash Reddy P

  80. micha kops Says:

    Hi,

    if you’d like to use an external database, simply configure it in the application container configuration by adding a new JDBC connection pool exporting a JNDI name and use this reference in your persistence.xml.

    For the logging – do you use the juli logger here?

  81. Morteza Vesal Says:

    Dear sir/madam,

    Thank you for your sample but i have an error when full out the create.xml and run the action

    the blogEntry is null and can not save in the database please help me.

  82. Morteza Vesal Says:

    Dear all,

    Thank you for the example but when i fill out the create.xml form and send for save the blogEntry is null and could not save in the database.

  83. Morteza Vesal Says:

    i can not create new artile in the create page some body can help me.when i send the argument th blogEntry is null.

  84. Micha Kops Says:

    Hi Morteza,

    are you using the same setup as in this article? Any exception/stracktrace logged?

  85. Morteza Vesal Says:

    yes,when i fill out the create form and send the data to the bean the blogEntry is null.

Search
Categories