当我使用spring mvc和hibernate事务时,我面临一个问题, 我尝试将dao与HQL一起使用来更新数据库,然后服务器抛出TransactionRequiredException,我检查了我的事务注释,ComponentScan和事务包,每种服务方法都可以正常工作,但是updateStock方法可以正常工作。
有人对此有相同或相似的问题吗?
有我的代码:
调度程序:
@Controller
public class ProductController {
@Autowired
productService pService;
@Autowired
ServletContext context;
@Autowired
orderService oService;
@RequestMapping(value = "/ConfirmOrder")
public String ConfirmOrder(HttpSession session) {
shoppingCart sc = (shoppingCart) session.getAttribute("shoppingCart");
orderBean ob = (orderBean) session.getAttribute("orderList");
Set<orderItemBean> items = new HashSet<orderItemBean>();
Map<Integer, orderItem> cart = sc.getContent();
Set<Integer> set = cart.keySet();
Integer newStock = 0;
int n = 0;
productBean mb = null;
for (Integer k : set) {
orderItem oi = cart.get(k);
Integer subtotal = (oi.getiQty() * oi.getpPrice());
String iDes = oi.getpName() + " 共 " + oi.getiQty().toString() + "個,金額小計:" + subtotal.toString();
orderItemBean oib = new orderItemBean(null, oi.getpId(), iDes, oi.getiQty(), oi.getpPrice());
oib.setOrderBean(ob);
items.add(oib);
mb = pService.getProduct(oi.getpId());
newStock = mb.getpInstock() - oi.getiQty();
n = pService.updateStock(oi.getpId(), newStock); //throw exception from here
}
ob.setItemSet(items);
oService.saveOrder(ob);
session.removeAttribute("shoppingCart");
return "redirect:/";
}
}
DAO:
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import config.GlobalService;
import product.Dao.productDao;
import product.model.productBean;
@Repository
public class productDaoImpl implements productDao {
int pageNo = 0;
SessionFactory factory;
public SessionFactory getFactory() {
return factory;
}
@Autowired
public void setFactory(SessionFactory factory) {
this.factory = factory;
}
public productDaoImpl() {
}
@Override
public int updateStock(int pId, int newStock) {
int n = 0;
Session session = factory.getCurrentSession();
String sql = "UPDATE productBean b SET b.pInstock = :stock WHERE b.pId = :id";
n = session.createQuery(sql).setParameter("stock", newStock).setParameter("id", pId).executeUpdate();
return n;
}
}
服务:
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import config.GlobalService;
import product.Dao.productDao;
import product.model.productBean;
import product.service.productService;
@Transactional
@Service
public class productServiceImpl implements productService {
productDao pdao;
SessionFactory factory;
public productDao getPdao() {
return pdao;
}
public SessionFactory getFactory() {
return factory;
}
@Autowired
public void setPdao(productDao pdao) {
this.pdao = pdao;
}
@Autowired
public void setFactory(SessionFactory factory) {
this.factory = factory;
}
public productServiceImpl() {
}
@Override
public List<productBean> getAllProduct() {
List<productBean> list = null;
list = pdao.getAllProduct();
return list;
}
@Override
public int insertNewProduct(productBean pb) {
int n = 0;
pdao.insertNewProduct(pb);
n++;
return n;
}
@Override
public productBean getProduct(int pId) {
productBean pb = null;
pb = pdao.getProduct(pId);
return pb;
}
@Override
public void setPageNo(int pageNo) {
pdao.setPageNo(pageNo);
}
@Override
public int getPageNo() {
return pdao.getPageNo();
}
@Override
public int getTotalPages() {
int totalPages = (int) (Math.ceil(getDataCount() / (double) GlobalService.dataPerPage));
return totalPages;
}
@Override
public Long getDataCount() {
return pdao.getDataCount();
}
@Override
public int updateStock(int pId, int newStock) {
return pdao.updateStock(pId, newStock);
}
}
WebAppConfig:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "dispatcherController, register, product, cart, checkout")
public class WebAppConfig extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver internalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/resource/css/");
registry.addResourceHandler("/img/**").addResourceLocations("/WEB-INF/resource/img/");
}
public WebAppConfig() {
}
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
resolver.setMaxUploadSize(81920000);
return resolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
RootAppConfig:
import java.beans.PropertyVetoException;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.mchange.v2.c3p0.ComboPooledDataSource;
@Configuration
@EnableTransactionManagement
public class RootAppConfig {
@Bean
public DataSource dataSource() {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setUser("sa");
ds.setPassword("sa123456");
try {
ds.setDriverClass("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (PropertyVetoException e) {
e.printStackTrace();
}
ds.setJdbcUrl("jdbc:sqlserver://localhost:1433;databaseName=PDB");
ds.setInitialPoolSize(4);
ds.setMaxPoolSize(8);
return ds;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setDataSource(dataSource());
factory.setPackagesToScan(new String[] { "product.model","register.model","cart.model" });
factory.setHibernateProperties(additionalProperties());
return factory;
}
@Bean(name="transactionManager")
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
private Properties additionalProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", org.hibernate.dialect.SQLServer2012Dialect.class);
properties.put("hibernate.show_sql", Boolean.TRUE);
properties.put("hibernate.format_sql", Boolean.TRUE);
properties.put("default_batch_fetch_size", 10);
properties.put("hibernate.hbm2ddl.auto", "update");
return properties;
}
}
WebInitializer:
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootAppConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebAppConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}