3

I am following a tutorial to integrate the Struts and Hibernate and getting a NullPointerException. The error I am getting is

 Sep 24, 2013 12:25:54 AM com.sun.faces.config.ConfigureListener contextInitialized
INFO: Initializing Sun's JavaServer Faces implementation (1.2_03-20070706-NIGHTLY)         for    context '/BookShop'
url isnull
log4j:WARN No appenders could be found for logger         (org.hibernate.type.BasicTypeRegistry).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
null
 <Sep 24, 2013 12:27:01 AM IST> <Error> <org.apache.struts2.dispatcher.Dispatcher>         <BEA-000000> <Exception occurred during     processing request: null
 java.lang.NullPointerException
at com.author.action.AuthorAction.listAuthor(AuthorAction.java:71)
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)
Truncated. see log file for complete stacktrace
> 

<Sep 24, 2013 12:27:01 AM IST>

Directory Structure:

enter image description here

enter image description here

Action file AuthorAction.java:

package com.author.action;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.struts2.ServletActionContext;
import org.hibernate.Session;
import org.hibernate.SessionFactory;


import com.author.listener.HibernateListener;
import com.author.model.Author;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@SuppressWarnings({ "serial", "unchecked" })
public class AuthorAction extends ActionSupport implements ModelDriven{

Author author = new Author();
List<Author> authorList = new ArrayList<Author>();

public String execute() throws Exception {
    return SUCCESS;
}

public Object getModel() {
    return author;
}
public List<Author> getAuthorList() {
    return authorList;
}

public void setAuthorList(List<Author> authorList) {
    this.authorList = authorList;
}

//save customer
public String addAuthor() throws Exception{

    //get hibernate session from the servlet context
    SessionFactory sessionFactory = 
         (SessionFactory) ServletActionContext.getServletContext()
                 .getAttribute(HibernateListener.KEY_NAME);

    Session session = sessionFactory.openSession();

    //save it
    author.setCreatedDate(new Date());

    session.beginTransaction();
    System.out.println("the value which is to be saved is"+author);
    session.save(author);
    session.getTransaction().commit();

    //reload the customer list
    authorList = null;
    authorList = session.createQuery("from author").list();
    System.out.println(" the author list is"+authorList);
    return SUCCESS;

}

//list all customers
public String listAuthor() throws Exception{

    //get hibernate session from the servlet context
    SessionFactory sessionFactory = 
         (SessionFactory) ServletActionContext.getServletContext()
                 .getAttribute(HibernateListener.KEY_NAME);

    Session session = sessionFactory.openSession();

    authorList = session.createQuery("from author").list();

    return SUCCESS;

}



    
}

Hibernate listener file:

package com.author.listener;

import java.net.URL;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateListener implements ServletContextListener{

private Configuration config;
private SessionFactory factory;
private String path = "src/resources/hibernate.cfg.xml";
@SuppressWarnings("unchecked")
private static Class clazz = HibernateListener.class;

public static final String KEY_NAME = clazz.getName();

public void contextDestroyed(ServletContextEvent event) {
  //
}

public void contextInitialized(ServletContextEvent event) {

 try { 
        URL url = HibernateListener.class.getResource(path);
        System.out.println("url is"+url);
        config = new Configuration().configure(url);
        
        factory = config.buildSessionFactory();

        //save the Hibernate session factory into serlvet context
        event.getServletContext().setAttribute(KEY_NAME, factory);
  } catch (Exception e) {
         System.out.println(e.getMessage());
   }
}
}

My model file Author.java:

package com.author.model;
import java.util.Date;
public class Author{
private Long customerId;
private String name;
private String address;
private Date createdDate;
public Long getCustomerId() {
    return customerId;
}
public void setCustomerId(Long customerId) {
    this.customerId = customerId;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}
public Date getCreatedDate() {
    return createdDate;
}
public void setCreatedDate(Date createdDate) {
    this.createdDate = createdDate;
}
}

hibernate.cfg.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/bookshop</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">false</property>
   <mapping resource="com/author/hibernate/Author.hbm.xml" />
  </session-factory>
</hibernate-configuration>

Hibernate Mapping file Author.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.mkyong.customer.model.Customer" 
table="customer" catalog="mkyong">

    <id name="customerId" type="java.lang.Long">
        <column name="CUSTOMER_ID" />
        <generator class="identity" />
    </id>
    <property name="name" type="string">
        <column name="NAME" length="45" not-null="true" />
    </property>
    <property name="address" type="string">
        <column name="ADDRESS" not-null="true" />
    </property>
    <property name="createdDate" type="timestamp">
        <column name="CREATED_DATE" length="19" not-null="true" />
    </property>
</class>
</hibernate-mapping>

JSP File Author.jsp:

<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
</head>

<body>
<h1>Struts 2 + Hibernate integration example</h1>

 <h2>Add Customer</h2>
 <s:form action="addAuthorAction" >
     <s:textfield name="name" label="Name" value="" />
 <s:textarea name="address" label="Address" value="" cols="50" rows="5" />
  <s:submit />
</s:form>

 <h2>All Customers</h2>

<s:if test="authorList.size() > 0">
 <table border="1px" cellpadding="8px">
    <tr>
    <th>Customer Id</th>
    <th>Name</th>
    <th>Address</th>
    <th>Created Date</th>
</tr>
<s:iterator value="authorList" status="userStatus">
    <tr>
        <td><s:property value="customerId" /></td>
        <td><s:property value="name" /></td>
        <td><s:property value="address" /></td>
        <td><s:date name="createdDate" format="dd/MM/yyyy" /></td>
    </tr>
</s:iterator>
</table>
</s:if>
<br/>
<br/>

</body>
</html>

struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
  <constant name="struts.devMode" value="false" />

  <package name="default" namespace="/" extends="struts-default">

    <action name="addAuthorAction" 
class="com.author.action.AuthorAction" method="addAuthor" >
   <result name="success">pages/Author.jsp</result>
</action>

<action name="listAuthorAction" 
class="com.author.action.AuthorAction" method="listAuthor" >
    <result name="success">pages/Author.jsp</result>
</action>       

  </package>    
</struts>

web.xml:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Bookshop</display-name>

  <filter>
<filter-name>struts2</filter-name>
<filter-class>
  org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
  </filter>

  <filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
  </filter-mapping>

  <listener>
    <listener-class>com.author.listener.HibernateListener
     </listener-class>
   </listener>

</web-app>
Roman C
  • 49,761
  • 33
  • 66
  • 176
user251287
  • 101
  • 1
  • 3
  • 12

2 Answers2

2

We are in year 2013, so you don't need to use XML to describe your Hibernate Models and you don't need XML do define your Struts2 Actions (See Struts2 Convention Plugin).

To handle your Hibernate Session (It look like this is your problem) you can use the Struts2 Hibernate Plugin, simply write a Interceptor for Session Handling or my preferred Solution use Spring as DI and let spring inject your repositories and handle your sessions.

As a real life example take a look at the Struts2 Todo App.

Johannes
  • 2,060
  • 3
  • 17
  • 27
1

In your code you have failed to build the session factory, hence the NullPointerException.

This is a common error and it means that something wrong is going in the code. In the code above you build the session factory on context initialize event instead of delegation it to HibernateUtil, which is a recommended way to manually build the session factory.

In this answer explained how to build the session factory.

To fix error while configuring the Hibernate you need to write this code:

config = new Configuration().configure("/hibernate.cfg.xml");

The hibernate.cfg.xml file should be on classpath like in your example.

Community
  • 1
  • 1
Roman C
  • 49,761
  • 33
  • 66
  • 176