我最近开始使用去年学习 Ruby 的 Java 后端。我正在尝试做一个简单的“发布”操作,将联系人保存到 MySQL 数据库。(请原谅新手问题)。
我正在使用条纹、JPA 和休眠。我一直在关注关于为 MVC 设置环境的Stripes 书,但我有点陷入以下错误,我希望有人能指出我正确的方向。我知道错误说我有一个未处理的异常,但我还不够新,我不确定这是否是错误的真正原因,我不确定它是 Hibernate、Java 还是 Stripes 问题。我确定我错过了一些东西,我只是不确定是什么。我将错误与我的一些代码一起发布。
谢谢您的帮助
错误:
Feb 19, 2013 6:13:38 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [StripesDispatcher] in context with path [] threw exception [Unhandled exception in exception handler.] with root cause
java.lang.NullPointerException
at veexterior.DAO.impl.BaseDaoImpl.save(BaseDaoImpl.java:46)
at veexterior.action.ContactActionBean.save(ContactActionBean.java:36)
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 net.sourceforge.stripes.controller.DispatcherHelper$6.intercept(DispatcherHelper.java:456)
at net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:158)
at net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor.intercept(BeforeAfterMethodInterceptor.java:113)
at net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:155)
at net.sourceforge.stripes.controller.ExecutionContext.wrap(ExecutionContext.java:74)
at net.sourceforge.stripes.controller.DispatcherHelper.invokeEventHandler(DispatcherHelper.java:454)
at net.sourceforge.stripes.controller.DispatcherServlet.invokeEventHandler(DispatcherServlet.java:278)
at net.sourceforge.stripes.controller.DispatcherServlet.service(DispatcherServlet.java:160)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilter.java:260)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
BaseDAOImpl
package veexterior.DAO.impl;
import org.stripesstuff.stripersist.Stripersist;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import javax.persistence.NonUniqueResultException;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import java.util.List;
import veexterior.DAO.Dao;
import veexterior.models.Contact;
public abstract class BaseDaoImpl<T,ID extends Serializable>
implements Dao<T,ID>
{
private Class<T> entityClass;
@SuppressWarnings("unchecked")
public BaseDaoImpl() {
entityClass = (Class<T>)
((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
/* methods... */
@SuppressWarnings("unchecked")
public List<T> read() {
return Stripersist.getEntityManager()
.createQuery("from " + entityClass.getName())
.getResultList();
}
public T read(ID id) {
return Stripersist.getEntityManager().find(entityClass, id);
}
@SuppressWarnings("unchecked")
public void save(T object) {
Stripersist.getEntityManager().persist(object);
}
public void delete(T object) {
Stripersist.getEntityManager().remove(object);
}
public void commit() {
Stripersist.getEntityManager().getTransaction().commit();
}
@SuppressWarnings("unchecked")
public T findBy(String fieldName, Object value) {
Query query = Stripersist.getEntityManager()
.createQuery(getQuery(fieldName, null))
.setParameter(fieldName, value);
return getSingleResult(query);
}
private String getQuery(String fieldName, Contact contact){
String query =
"from " + entityClass.getName() + " t " +
"where t." + fieldName + " = :" + fieldName;
if (contact == null) {
return query;
}
return query + " and t.user = :user";
}
@SuppressWarnings("unchecked")
private T getSingleResult(Query query) {
try {
return (T) query.getSingleResult();
}
catch (NonUniqueResultException exc) {
return (T) query.getResultList().get(0);
}
catch (NoResultException exc) {
return null;
}
}
}
联系ActionBean
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package veexterior.action;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
//import net.sourceforge.stripes.action.SimpleMessage;
import veexterior.models.Contact;
/**
*
* @author dave
*/
public class ContactActionBean extends BaseActionBean {
private static final String FORM="/WEB-INF/contactus.jsp";
private Contact contact;
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
@DefaultHandler
public Resolution form() {/* (1) */
return new ForwardResolution(FORM);
}
public Resolution save() {
Contact contact = getContact();
contactDao.save(contact);
contactDao.commit();
return new RedirectResolution(ContactActionBean.class);
}
}
用于提交的表格
<stripes:form beanclass="veexterior.action.ContactActionBean">
<div class="control-group">
<!-- <label class="control-label" for="inputEmail">Email</label>-->
<div class="controls">
<input type="text" id="inputEmail" placeholder="Email" name="contact.email">
</div>
</div>
<div class="control-group">
<!-- <label class="control-label" for="inputName">Name</label>-->
<div class="controls">
<input type="text" id="inputName" placeholder="Full Name" name="contact.name">
</div>
</div>
<div class="control-group">
<!-- <label class="control-label" for="inputName">Company</label>-->
<div class="controls">
<input type="text" id="inputName" placeholder="Company" name="contact.company">
</div>
</div>
<div class="control-group">
<textarea rows="5" class="input-xlarge" id="contactusmessage" name="contact.message" placeholder="Enter your message details."></textarea>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn" name="save">Send it</button>
</div>
</div>
</stripes:form>
我一直在关注的书中的一些代码
package stripesbook.dao.impl.stripersist;
import org.stripesstuff.stripersist.Stripersist;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import javax.persistence.NonUniqueResultException;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import stripesbook.dao.Dao;
import stripesbook.model.User;
public abstract class BaseDaoImpl<T,ID extends Serializable>
implements Dao<T,ID>
{
private Class<T> entityClass;
@SuppressWarnings("unchecked")
public BaseDaoImpl() {
entityClass = (Class<T>)
((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
/* methods... */
@SuppressWarnings("unchecked")
public List<T> read() {
return Stripersist.getEntityManager()
.createQuery("from " + entityClass.getName())
.getResultList();
}
public T read(ID id) {
return Stripersist.getEntityManager().find(entityClass, id);
}
@SuppressWarnings("unchecked")
public void save(T object) {
Stripersist.getEntityManager().persist(object);
}
public void delete(T object) {
Stripersist.getEntityManager().remove(object);
}
public void commit() {
Stripersist.getEntityManager().getTransaction().commit();
}
@SuppressWarnings("unchecked")
public T findBy(String fieldName, Object value) {
Query query = Stripersist.getEntityManager()
.createQuery(getQuery(fieldName, null))
.setParameter(fieldName, value);
return getSingleResult(query);
}
@SuppressWarnings("unchecked")
public T findBy(String fieldName, Object value, User user) {
Query query = Stripersist.getEntityManager()
.createQuery(getQuery(fieldName, user))
.setParameter(fieldName, value)
.setParameter("user", user);
return getSingleResult(query);
}
private String getQuery(String fieldName, User user){
String query =
"from " + entityClass.getName() + " t " +
"where t." + fieldName + " = :" + fieldName;
if (user == null) {
return query;
}
return query + " and t.user = :user";
}
@SuppressWarnings("unchecked")
private T getSingleResult(Query query) {
try {
return (T) query.getSingleResult();
}
catch (NonUniqueResultException exc) {
return (T) query.getResultList().get(0);
}
catch (NoResultException exc) {
return null;
}
}
}
XML 文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>MyAppsNAme</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
<init-param>
<param-name>ActionResolver.Packages</param-name>
<param-value>veexterior</param-value>
</init-param>
<init-param>
<param-name>Extension.Packages</param-name>
<param-value>org.stripesstuff.stripersist</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<servlet-name>StripesDispatcher</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>StripesDispatcher</servlet-name>
<servlet-class>net.sourceforge.stripes.controller.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>StripesDispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
Persistence.xml 文件
<?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="persistence" transaction-type="RESOURCE_LOCAL">
<!-- Tell JPA to use Hibernate -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<!-- Autodetect entity classes -->
<property name="hibernate.archive.autodetection" value="class"/>
<!-- Automatically create the SQL schema -->
<property name="hibernate.hbm2ddl.auto" value="update"/>
<!-- Tell Hibernate to use MySQL -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.url" value="Local MySQL Address"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<!-- Configure the connection pool -->
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="3000"/>
</properties>
</persistence-unit>
</persistence>