7/29/2011

Example of JPA and Hibernate with JBoss and MySql

This post demonstrates how to write a simple web app using Java Persistence API (JPA), EJB 3 session bean and servlet, connecting to MySql database, and deployed to JBoss appserver 6.

1, JPA entity class, Greeting, is the same as in my previous example, also included here in its entirety:

package test;
import java.io.Serializable;
import javax.persistence.*;

@Entity
public class Greeting implements Serializable {
@Id @GeneratedValue private int id;
@Basic private String message;
@Basic private String language;

public Greeting() {}

public Greeting(String message, String language) {
this.message = message;
this.language = language;
}

public String toString() {
return "Greeting id=" + id + ", message=" + message +
", language=" + language;
}
}
2, a stateless session bean facade for CRUD operations with container-managed transaction and container-managed persistence context:
package test;
import javax.ejb.*;
import javax.persistence.*;

@Stateless
public class GreetingBean {
@PersistenceContext
private EntityManager em;

public void create(Greeting... gs) {
for(Greeting g : gs) {
em.persist(g);
}
}

public Greeting findByLang(String lang) {
return (Greeting) em.createQuery(
"select g from Greeting g where g.language = :language")
.setParameter("language", lang).getSingleResult();
}
}
3, TestServlet, which calls the stateless session bean:
package test;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.ejb.EJB;

@javax.servlet.annotation.WebServlet(urlPatterns = "/*")
public class TestServlet extends HttpServlet {
@EJB
private GreetingBean bean;

protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
Greeting g_en = new Greeting("hello world", "en");
Greeting g_es = new Greeting("hola, mundo", "es");
bean.create(g_en, g_es);
out.println("Created and persisted " + g_en + ", and " + g_es);

Greeting g = bean.findByLang("en");
out.println("Query returned: " + g);
}

@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
4, persistence.xml with JTA transaction using a MySQL datasource:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_2_0.xsd"
version="2.0">
<persistence-unit name="greeting-pu" transaction-type="JTA">
<!--
<jta-data-source>java:/DefaultDS</jta-data-source>
-->
<jta-data-source>java:/MySqlDS</jta-data-source>
<properties>
<!--
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
-->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>
5, create the MySql datasource in JBoss appserver:
cp $JBOSS_HOME/docs/examples/jca/mysql-ds.xml $JBOSS_HOME/server/default/deploy/
# change user-name and password elements in mysql-ds.xml
cp $HOME/downloads/mysql-connector-java-5.1.15-bin.jar $JBOSS_HOME/server/default/lib/
6, compile and package class files and persistence.xml into test.war:
javac -d ../ -cp "$JBOSS_HOME/client/*" *.java

content of test.war:
====================
WEB-INF/classes/META-INF/persistence.xml
WEB-INF/classes/test/Greeting.class
WEB-INF/classes/test/GreetingBean.class
WEB-INF/classes/test/TestServlet.class
7, start MySql database server, JBoss default server and deploy test.war:
cd /usr/local/mysql-5.1.32
sudo bin/mysqld_safe --user root

$JBOSS_HOME/bin/run.sh
8, deploy and run the test:
cp test.war $JBOSS_HOME/server/default/deploy
curl http://localhost:8080/test/
If you use the default HyperSonic embedded database in JBoss AS, instead of MySql database server, make the following adjustments:

(a), toggle the comments in persistence.xml;
(b), no need to copy mysql-ds.xml, or MySql driver jar;
(c), no need to start MySql database server.

5 comments:

Surya said...

Good one. thanks

RAMROD said...

Great example ...any chance you might know what changes are necessary for JBoss 5 ...@WebServlet does not seem to be supported in JBoss 5.

javahowto said...

I don't think @WebServlet will be ported to JBoss 5. @WebServlet is introduced in Servlet 3.0, which is part of JavaEE 6. JBoss 6 is what you will need.

Frode said...

What if you wanted to change the greeting after retrieving it from the service ? Would you then have to create a new method in the service in order to update the retrieved entity ?

Wouldn't it have been better to actually have the Entitymanager inside the servlet so the transaction lasts as long as the servlet-method is running ? This way you don't need to explicity call a save-method after changing the greeting...

Andrew Karzhou said...

I try to run this example but
GreetingBean bean=null;

Why it happens