刚学完SSH没多久,写一个demo项目的时候遇到这个问题。
我的配置基本都是使用注解配置的,只有dao层是在xml文件中配置。
service层代码:
package com.xushuai.crm.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.xushuai.crm.dao.CustomerDao;
import com.xushuai.crm.domain.Customer;
import com.xushuai.crm.service.CustomerService;
import com.xushuai.crm.utils.PageBean;
@Service("customerService")
@Transactional(readOnly=true)
public class CustomerServiceImpl implements CustomerService {
@Resource(name="customerDao")
private CustomerDao customerDao;
public void setCustomerDao(CustomerDao customerDao) {
this.customerDao = customerDao;
}
/**
* 获取PageBean,用于显示到页面
*/
public PageBean<Customer> getPageBean(DetachedCriteria dc, Integer pageSize, Integer currentPage) {
/*
* 1.查询总记录数
* 2.创建PageBean对象
* 3.查询出符合条件的list,并赋值给PageBean
* 4.返回PageBean
*/
int totalCount = customerDao.getTotalCount(dc);
PageBean<Customer> pb = new PageBean<Customer>(currentPage, totalCount, pageSize);
List<Customer> list = customerDao.getList(dc, pb.getStart(), pb.getPageSize());
pb.setList(list);
return pb;
}
/**
* 保存客户
*/
public void save(Customer customer) {
//System.out.println("service" + customerDao);
customerDao.save(customer);
}
}
dao层代码:
package com.xushuai.crm.dao.impl;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import com.xushuai.crm.dao.BaseDao;
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
private Class clazz;//用于接收运行期泛型类型
public BaseDaoImpl() {
//获得当前类型的带有泛型类型的父类
ParameterizedType ptClass = (ParameterizedType) this.getClass().getGenericSuperclass();
//获得运行期的泛型类型
clazz = (Class) ptClass.getActualTypeArguments()[0];
}
public void save(T t) {
getHibernateTemplate().save(t);
}
public void delete(T t) {
getHibernateTemplate().delete(t);
}
public void delete(Serializable id) {
T t = this.getById(id);//先取,再删
getHibernateTemplate().delete(t);
}
public void update(T t) {
getHibernateTemplate().update(t);
}
public T getById(Serializable id) {
return (T) getHibernateTemplate().get(clazz, id);
}
public Integer getTotalCount(DetachedCriteria dc) {
//设置查询的聚合函数,总记录数
dc.setProjection(Projections.rowCount());
List<Long> list = (List<Long>) getHibernateTemplate().findByCriteria(dc);
//清空之前设置的聚合函数
dc.setProjection(null);
if(list!=null && list.size()>0){
Long count = list.get(0);
return count.intValue();
}else{
return null;
}
}
public List<T> getList(DetachedCriteria dc, Integer start, Integer pageSize) {
List<T> list = (List<T>) getHibernateTemplate().findByCriteria(dc, start, pageSize);
return list;
}
public void saveOrUpdate(T t) {
getHibernateTemplate().saveOrUpdate(t);
}
}
action代码:
package com.xushuai.crm.web.action;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.xushuai.crm.domain.Customer;
import com.xushuai.crm.service.CustomerService;
import com.xushuai.crm.utils.PageBean;
//接收参数-模型驱动
@SuppressWarnings("serial")
@Controller("customerAction")
@Scope("prototype")
public class CustomerAction extends ActionSupport implements ModelDriven<Customer>{
private Customer customer = new Customer();
@Resource(name="customerService")
private CustomerService customerService;
private Integer pageSize;
private Integer currentPage;
/*
* 显示客户列表
*/
public String list() throws Exception {
//封装离线查询对象
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
if(StringUtils.isNotBlank(customer.getCust_name())){
dc.add(Restrictions.like("cust_name", "%" + customer.getCust_name() + "%"));
}
/*
* 1.调用service#list()查询PageBean
* 2.将pageBeab保存,转发到页面显示
*/
PageBean<Customer> pb = customerService.getPageBean(dc,pageSize,currentPage);
ActionContext.getContext().put("pb", pb);
return "list";
}
public String add() throws Exception {
//---------------------------------------------------------------------
//1 调用Service,保存Customer对象
//System.out.println("action" + customerService);
customerService.save(customer);
//2 重定向到客户列表Action
return "to";
}
public Customer getModel() {
return customer;
}
public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
}
struts配置:
<action name="CustomerAction_*" class="customerAction" method="{1}" >
<result name="list" >/jsp/customer/list.jsp</result>
<result name="to" type="redirectAction" >
<param name="namespace">/</param>
<param name="actionName">CustomerAction_list</param>
</result>
</action>
以上是未修改的代码:
在我执行的时候,save操作一直执行不了。通过debug查出action方法确实是有进入,但是就是不知道为什么会插入不了,
最开始我以为是配置错误,检查过后,发现配置并没有问题。然后检查逻辑是否有错误,也没有发现错误。最后将错误锁定在事务的操作上,因为我执行Action中的list方法时,是有返回的。然后看到Service层的代码中,默认所有的方法操作,都是只读的。所以我们只需要在Service层的save()方法上添加注解即可。
修正后的Service层代码:
package com.xushuai.crm.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.xushuai.crm.dao.CustomerDao;
import com.xushuai.crm.domain.Customer;
import com.xushuai.crm.service.CustomerService;
import com.xushuai.crm.utils.PageBean;
@Service("customerService")
@Transactional(readOnly=true)
public class CustomerServiceImpl implements CustomerService {
@Resource(name="customerDao")
private CustomerDao customerDao;
public void setCustomerDao(CustomerDao customerDao) {
this.customerDao = customerDao;
}
/**
* 获取PageBean,用于显示到页面
*/
public PageBean<Customer> getPageBean(DetachedCriteria dc, Integer pageSize, Integer currentPage) {
/*
* 1.查询总记录数
* 2.创建PageBean对象
* 3.查询出符合条件的list,并赋值给PageBean
* 4.返回PageBean
*/
int totalCount = customerDao.getTotalCount(dc);
PageBean<Customer> pb = new PageBean<Customer>(currentPage, totalCount, pageSize);
List<Customer> list = customerDao.getList(dc, pb.getStart(), pb.getPageSize());
pb.setList(list);
return pb;
}
/**
* 保存客户
*/
@Transactional(readOnly=false)
public void save(Customer customer) {
//System.out.println("service" + customerDao);
customerDao.save(customer);
}
}
然后运行就可以执行save操作了。
就是这么简单的一个问题,困扰了大半天。也算是给自己一个教训吧。希望自己引以为戒。如果你也遇见类似问题,可能会对你有所帮助。