Spring配置文件applicationContext中原先使用的是Hibernate,現在改為Hibernate對JPA的支持;增加了C3P0連接池;修改了Dao操作實現,改為Spring接管的JPA實現。 如果讀者想詳細查看Spring整合Jersey與前端交互可以點擊上述連接。本文主要介紹以上三處修改內容,並且使用Jersey Test測試整合結果正確性。博文最後提供源碼下載。至於JPA的介紹也不是本文的重點,若讀者有不明白的地方可以查看其它文檔。
一、添加pom依賴
因為整個項目構建是基於Maven的,所以在使用JPA和C3P0連接池之前,必須先添加相應的依賴JAR包,具體如下:
<!--{cke_protected}{C}%3C!%2D%2D%20hibernate%E5%AF%B9JPA%E6%94%AF%E6%8C%81%20%2D%2D%3E--> <dependency> <groupid>org.hibernate</groupid> <artifactid>hibernate-entitymanager</artifactid> <version>4.3.11.Final</version> </dependency> <!--{cke_protected}{C}%3C!%2D%2D%20hibernate%20C3P0%E8%BF%9E%E6%8E%A5%E6%B1%A0%E5%8C%85%20%2D%2D%3E--> <dependency> <groupid>org.hibernate</groupid> <artifactid>hibernate-c3p0</artifactid> <version>4.3.11.Final</version> </dependency> <dependency> <groupid>com.mchange</groupid> <artifactid>c3p0</artifactid> <version>0.9.2.1</version> </dependency> <dependency> <groupid>com.mchange</groupid> <artifactid>mchange-commons-java</artifactid> <version>0.2.3.4</version> </dependency>
目前比較成熟的 JPA 框架主要包括 Jboss 的 Hibernate EntityManager、Oracle 捐獻給 Eclipse 社區的 EclipseLink、Apache 的 OpenJPA 等,如上所示,本文使用的是Hibernate的JPA支持。
二、修改applicationContext.xml
正如Spring接管Hibernate一樣,JAP也可以由Spring接管,只需要在applicationContext.xml文件做相應的配置即可,用戶便無需關注諸如事務、安全等非業務邏輯的處理及實現。如下為修改後的Spring配置文件。
<!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%2D%2D%3E--> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81%20%2D%2D%3E--> <context:annotation-config> <!--{cke_protected}{C}%3C!%2D%2D%20%E5%90%AF%E5%8A%A8%E7%BB%84%E4%BB%B6%E6%89%AB%E6%8F%8F%20%2D%2D%3E--> <context:component-scan base-package="com.spring.jersy.jpa.hibernate.resource,com.spring.jersy.jpa.hibernate.dao,com.spring.jersy.jpa.hibernate.service"> <!--{cke_protected}{C}%3C!%2D%2D%20JDBC%E5%B1%9E%E6%80%A7%E6%96%87%E4%BB%B6%E4%BD%8D%E7%BD%AE%20%2D%2D%3E--> <context:property-placeholder location="classpath:com/spring/jersy/jpa/hibernate/config/jdbc.properties"> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%20%2D%2D%3E--> <!--{cke_protected}{C}%3C!%2D%2D%20%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E9%85%8D%E7%BD%AE%E8%BF%9E%E6%8E%A5%E6%B1%A0org.apache.commons.dbcp.BasicDataSource%E5%88%99%E4%B8%8D%E7%AC%A6%E5%90%88%20%2D%2D%3E--> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource"> <property name="driverClass" value="${jdbc.driverClassName}"> <property name="jdbcUrl" value="${jdbc.url}"> <property name="user" value="${jdbc.username}"> <property name="password" value="${jdbc.password}"> <!--{cke_protected}{C}%3C!%2D%2D%20hibernate.c3p0.min_size%3A%20%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%E7%9A%84%E6%9C%80%E5%B0%8F%E8%BF%9E%E6%8E%A5%E6%95%B0%20%2D%2D%3E--> <property name="minPoolSize" value="${jdbc.minPoolSize}"> <!--{cke_protected}{C}%3C!%2D%2D%20hibernate.c3p0.max_size%3A%20%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%E7%9A%84%E6%9C%80%E5%A4%A7%E8%BF%9E%E6%8E%A5%E6%95%B0%20%2D%2D%3E--> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%8C%87%E5%AE%9A%E8%BF%9E%E6%8E%A5%E6%B1%A0%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E8%BF%9E%E6%8E%A5%E6%95%B0%20%20%E5%8F%96%E5%80%BC%E5%BA%94%E5%9C%A8minPoolSize%20%E4%B8%8E%20maxPoolSize%20%E4%B9%8B%E9%97%B4.Default%3A3%2D%2D%3E--> <property name="initialPoolSize" value="${jdbc.initialPoolSize}"> <!--{cke_protected}{C}%3C!%2D%2D%20%E7%BC%93%E5%AD%98%20Statement%20%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%95%B0%E9%87%8F%20%2D%2D%3E--> <property name="maxStatements" value="${jdbc.maxStatements}"> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%E4%B8%AD%E8%BF%9E%E6%8E%A5%E5%AF%B9%E8%B1%A1%E5%9C%A8%E5%A4%9A%E9%95%BF%E6%97%B6%E9%97%B4%E6%B2%A1%E6%9C%89%E4%BD%BF%E7%94%A8%E8%BF%87%E5%90%8E%EF%BC%8C%E5%B0%B1%E5%BA%94%E8%AF%A5%E8%A2%AB%E9%94%80%E6%AF%81%20%2D%2D%3E--> <property name="maxIdleTime" value="${jdbc.maxIdleTime}"> <!--{cke_protected}{C}%3C!%2D%2D%20%E8%A1%A8%E7%A4%BA%E8%BF%9E%E6%8E%A5%E6%B1%A0%E6%A3%80%E6%B5%8B%E7%BA%BF%E7%A8%8B%E5%A4%9A%E9%95%BF%E6%97%B6%E9%97%B4%E6%A3%80%E6%B5%8B%E4%B8%80%E6%AC%A1%E6%B1%A0%E5%86%85%E7%9A%84%E6%89%80%E6%9C%89%E9%93%BE%E6%8E%A5%E5%AF%B9%E8%B1%A1%E6%98%AF%E5%90%A6%E8%B6%85%E6%97%B6%20%2D%2D%3E--> <property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"> <!--{cke_protected}{C}%3C!%2D%2D%20%E5%BD%93%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%E4%B8%AD%E7%9A%84%E8%BF%9E%E6%8E%A5%E8%80%97%E5%B0%BD%E6%97%B6%2C%20%E5%90%8C%E4%B8%80%E6%97%B6%E5%88%BB%E8%8E%B7%E5%8F%96%E5%A4%9A%E5%B0%91%E4%B8%AA%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%20%2D%2D%3E--> <property name="acquireIncrement" value="${jdbc.acquireIncrement}"> </property></property></property></property></property></property></property></property></property></property></property></bean> <!--{cke_protected}{C}%3C!%2D%2D%20Hibernate%E5%AF%B9Jpa%E7%9A%84%E5%AE%9E%E7%8E%B0%20%2D%2D%3E--> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" id="hibernateJpaVendorAdapter"> <!--{cke_protected}{C}%3C!%2D%2D%20Jpa%20%E4%BA%8B%E5%8A%A1%E7%AE%A1%E7%90%86%E5%99%A8%20%2D%2D%3E--> <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"> </property></bean> <!--{cke_protected}{C}%3C!%2D%2D%20%E5%AE%9A%E4%B9%89%E5%AE%9E%E4%BD%93%E7%AE%A1%E7%90%86%E5%99%A8%E5%B7%A5%E5%8E%82%20Jpa%E9%85%8D%E7%BD%AE%20LocalContainerEntityManagerFactoryBean%E8%BF%99%E4%B8%AA%E9%80%89%E9%A1%B9Spring%E6%89%AE%E6%BC%94%E4%BA%86%E5%AE%B9%E5%99%A8%E7%9A%84%E8%A7%92%E8%89%B2%E3%80%82%E5%AE%8C%E5%85%A8%E6%8E%8C%E7%AE%A1JPA%20%2D%2D%3E--> <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%8C%87%E5%AE%9A%E6%95%B0%E6%8D%AE%E6%BA%90%20%2D%2D%3E--> <property name="dataSource" ref="dataSource"> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%8C%87%E5%AE%9AJpa%E6%8C%81%E4%B9%85%E5%8C%96%E5%AE%9E%E7%8E%B0%E5%8E%82%E5%95%86%E7%B1%BB%2C%E8%BF%99%E9%87%8C%E4%BB%A5Hibernate%E4%B8%BA%E4%BE%8B%20%2D%2D%3E--> <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%8C%87%E5%AE%9AEntity%E5%AE%9E%E4%BD%93%E7%B1%BB%E5%8C%85%E8%B7%AF%E5%BE%84%20%2D%2D%3E--> <property name="packagesToScan"> <array> <value>com.spring.jersy.jpa.hibernate.model</value> </array> </property> <!--{cke_protected}{C}%3C!%2D%2D%20%E6%8C%87%E5%AE%9AJPA%E5%B1%9E%E6%80%A7%EF%BC%9B%E5%A6%82Hibernate%E4%B8%AD%E6%8C%87%E5%AE%9A%E6%98%AF%E5%90%A6%E6%98%BE%E7%A4%BASQL%E7%9A%84%E6%98%AF%E5%90%A6%E6%98%BE%E7%A4%BA%E3%80%81%E6%96%B9%E8%A8%80%E7%AD%89%20%2D%2D%3E--> <property name="jpaProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> </props> </property> </property></property></bean> <!--{cke_protected}{C}%3C!%2D%2D%20%E9%85%8D%E7%BD%AE%E4%BA%8B%E5%8A%A1%E7%89%B9%E6%80%A7%EF%BC%8C%E9%85%8D%E7%BD%AEadd%EF%BC%8Cdelete%EF%BC%8Cupdate%E5%BC%80%E5%A7%8B%E7%9A%84%E6%96%B9%E6%B3%95%EF%BC%8C%E4%BA%8B%E5%8A%A1%E4%BC%A0%E6%92%AD%E7%89%B9%E6%80%A7%E4%B8%BArequired%20%2D%2D%3E--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED"> <tx:method name="delete*" propagation="REQUIRED"> <tx:method name="update*" propagation="REQUIRED"> <tx:method name="*" read-only="true"> </tx:method></tx:method></tx:method></tx:method></tx:attributes> </tx:advice> <!--{cke_protected}{C}%3C!%2D%2D%20%E9%85%8D%E7%BD%AE%E9%82%A3%E4%BA%9B%E7%B1%BB%E7%9A%84%E6%96%B9%E6%B3%95%E8%BF%9B%E8%A1%8C%E4%BA%8B%E5%8A%A1%E7%AE%A1%E7%90%86%EF%BC%8C%E5%BD%93%E5%89%8D%3Cspan%20style%3D%22font-family%3A%20Arial%2C%20Helvetica%2C%20sans-serif%3B%22%3Ecom.spring.jersy.jpa.hibernate.service%3C%2Fspan%3E%E5%8C%85%E4%B8%AD%E7%9A%84%E5%AD%90%E5%8C%85%EF%BC%8C%20%E7%B1%BB%E4%B8%AD%E6%89%80%E6%9C%89%E6%96%B9%E6%B3%95%E9%9C%80%E8%A6%81%EF%BC%8C%E8%BF%98%E9%9C%80%E8%A6%81%E5%8F%82%E8%80%83tx%3Aadvice%E7%9A%84%E8%AE%BE%E7%BD%AE%20%2D%2D%3E--> <aop:config> <aop:pointcut expression="execution(* com.spring.jersy.jpa.hibernate.service.*.*(..))" id="allManagerMethod"> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"> </aop:advisor></aop:pointcut></aop:config> </bean></context:property-placeholder></context:component-scan></context:annotation-config></beans>jdbc.properties內容如下:
#MySQL jdbc jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=root #c3p0 jdbc.minPoolSize=5 jdbc.maxPoolSize=20 jdbc.initialPoolSize=15 jdbc.maxStatements=50 jdbc.maxIdleTime=300 jdbc.idleConnectionTestPeriod=60 jdbc.acquireIncrement=2三、修改Dao實現
之前使用Hibernate作為持久層框架時,Spring提供了HibernateTemplate對數據庫的CRUD等各種操作的實現。現在我們使用JPA操作時,Spring在配置文件中實現了EntityManagerFactory的注入實現,但是並沒有提供EntityManager的實現。如果每次都要使用工廠類生成實體管理器,則非常不利於開發。JPA提供了@PersistenceContext注解才解決這個問題。如下:
package com.spring.jersy.jpa.hibernate.dao; import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.springframework.stereotype.Repository; import com.spring.jersy.jpa.hibernate.model.User; @Repository(value = "userJpaDao") public class UserJpaDao { //通過該注解,在類中便無需EntityManagerFactory創建EntityManager了。 @PersistenceContext private EntityManager entityManager; // 根據用戶名和密碼查詢 public List四、業務層實現findByNameAndPassword(User user) { //如果sql語句中 select 有部分字段或者全部字段,返回的都是對象數組 String jql = "select u " + " from User u where u.username=:username and u.password = :password"; Query query = entityManager.createQuery(jql); query.setParameter("username", user.getUsername()); query.setParameter("password", user.getPassword()); @SuppressWarnings("unchecked") List listUsers = (List ) query.getResultList(); return listUsers; } //根據姓名查詢 @SuppressWarnings("unchecked") public List findUserByName(String name) { List userList = new ArrayList (); String jql = "from User u where u.username like:name"; Query query = entityManager.createQuery(jql); query.setParameter("name", name); userList = (List ) query.getSingleResult(); return userList; } //添加用戶 public boolean addUser(User user) { try { entityManager.persist(user); } catch (Exception e) { return false; } return true; } //刪除用戶 public boolean deleteUser(Integer id) { try { User user = entityManager.find(User.class, id); if(user != null){ entityManager.remove(user); return true; }else { return false; } } catch (Exception e) { return false; } } //修改用戶 public boolean updateUser(User user){ try { String jql = "update User u set u.username = :name, u.password = :pwd, " + "u.address = :address, u.tel =:tel where u.id = :id"; Query query = entityManager.createQuery(jql); query.setParameter("name", user.getUsername()) .setParameter("pwd", user.getPassword()) .setParameter("address", user.getAddress()) .setParameter("tel", user.getTel()) .setParameter("id", user.getId()); if(query.executeUpdate() == 1){ return true; }else { return false; } } catch (Exception e) { return false; } } }
業務層實現不需要太多修改,只需引用JPA Dao實現即可。具體如下:
package com.spring.jersy.jpa.hibernate.service; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.spring.jersy.jpa.hibernate.dao.UserJpaDao; import com.spring.jersy.jpa.hibernate.model.User; @Service(value="userService") public class UserService { @Resource(name="userJpaDao") private UserJpaDao userJpaDao; public User findUserByNameAndPassword (User user) { List五、資源類listUsers = userJpaDao.findByNameAndPassword(user); if(listUsers.size() > 0) { return listUsers.get(0); } return null; } public User findUserByName (String name) { List listUsers = userJpaDao.findUserByName(name); if(listUsers.size() > 0) { return listUsers.get(0); } return null; } public boolean deleteUser(Integer id) { return userJpaDao.deleteUser(id); } public boolean addUser(User user) { return userJpaDao.addUser(user); } public boolean updateUser(User user){ return userJpaDao.updateUser(user); } public UserJpaDao getUserJpaDao() { return userJpaDao; } public void setUserJpaDao(UserJpaDao userJpaDao) { this.userJpaDao = userJpaDao; } }
資源類實現主要是Jersey,本文因為上接Spring+Jersey+Hibernate+MySQL+HTML實現用戶信息增刪改查案例(附Jersey單元測試)文章,此處Jersey資源類不作任何修改,具體如下:
package com.spring.jersy.hibernate.resource; import javax.annotation.Resource; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import net.sf.json.JSONObject; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import com.spring.jersy.hibernate.model.User; import com.spring.jersy.hibernate.service.UserService; /** * Spring 使用Component注解Jersey資源類 * Path:相當於Spring MVC中的RequestMapping,用於HTTP URL請求 * Scope:表示Spring的單例模式或者原型模式prototype */ @Component @Path("/user") @Scope("prototype") public class UserResource { @Resource(name = "userService") private UserService userService; private String message; /** * GET:表示Jersey rest查詢請求 * Path:此處完整路徑需接類上面的Path,如:user/exist/xx/1233,才會跳轉到該方法處理 * Consumes:表示前端請求數據格式 * Produces:表示返回值數據格式 * PathParam:用於注解參數變量,與URL中對應的變量名對應,達到傳遞的作用 */ @GET @Path("/exist/{username}/{password}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) //查詢 public String isExist(@PathParam("username") String username, @PathParam("password") String password) { User user = new User(); user.setUsername(username); user.setPassword(password); User result = userService.findUserByNameAndPassword(user); /** * Spring+Jersey框架,不會主動幫助我們將傳遞的對象轉換成JSON數據格式, * 需使用JSON lib類中的JSONObject或者JSONArray轉換才能夠傳遞,否則前端 * 會報302錯誤。 */ JSONObject jsonUser = JSONObject.fromObject(result); return jsonUser.toString(); } @POST @Path("/addUser") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) //添加 public String addUser(User user) { boolean flag = userService.addUser(user); if (flag) { message = "success"; } else { message = "fail"; } JSONObject jsonObject = new JSONObject(); jsonObject.put("message", message); return jsonObject.toString(); } @DELETE @Path("/deleteUser/{id}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) //刪除 public String deleteUser(@PathParam("id") Integer id) { boolean flag = userService.deleteUser(id); if (flag) { message = "success"; } else { message = "fail"; } JSONObject jsonObject = new JSONObject(); jsonObject.put("message", message); return jsonObject.toString(); } @PUT @Path("/updateUser/{id}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) //修改 public String updateUser(@PathParam("id") Integer id, User user) { user.setId(id); boolean flag = userService.updateUser(user); if (flag) { message = "success"; } else { message = "fail"; } JSONObject jsonObject = new JSONObject(); jsonObject.put("message", message); return jsonObject.toString(); } public void setUserService(UserService userService) { this.userService = userService; } }六、單元測試
此處使用的單元測試是Jersey Test,測試類內容如下:
package com.spring.jersy.hibernate.test; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.request.RequestContextListener; import com.sun.jersey.spi.spring.container.servlet.SpringServlet; import com.sun.jersey.test.framework.JerseyTest; import com.sun.jersey.test.framework.WebAppDescriptor; /** * 主要加載web.xml中的配置信息 * @author Administrator * */ public abstract class BaseJerseyServiceTest extends JerseyTest { @Override protected WebAppDescriptor configure() { return new WebAppDescriptor.Builder("com.spring.jersy.jpa.hibernate.resource") .contextParam( "contextConfigLocation", "classpath:com/spring/jersy/hibernate/config/applicationContext.xml") //.servletClass(SpringServlet.class) .filterClass(SpringServlet.class) .initParam("com.sun.jersey.config.feature.Redirect", "true") .initParam("com.sun.jersey.config.feature.FilterForwardOn404", "true") .initParam("com.sun.jersey.config.property.WebPageContentRegex", "/(images|css|jsp)/.*") .initParam("com.sun.jersey.api.json.POJOMappingFeature", "true") .initParam("com.sun.jersey.config.property.packages", "com.spring.jersy.jpa.hibernate.resource") .contextListenerClass(ContextLoaderListener.class) .requestListenerClass(RequestContextListener.class) .build(); } }
package com.spring.jersy.jpa.hibernate.test; import javax.ws.rs.core.MediaType; import org.junit.Before; import org.junit.Test; import com.spring.jersy.jpa.hibernate.model.User; import com.sun.jersey.api.client.WebResource; public class UserResourceTest extends BaseJerseyServiceTest { private WebResource webResource; @Before public void setUp() throws Exception { webResource = resource(); // webResource.accept("application/json"); } @Test public void testIsExist() { String response = webResource.path("/user/exist/xx/1233").get( String.class); System.out.println(response); } @Test public void testAddUser() { User user = new User(); user.setUsername("wwwx"); user.setPassword("pwd"); user.setAddress("江蘇鹽城"); user.setTel("12333"); String response = webResource.path("/user/addUser") .entity(user, "application/json").post(String.class, user); System.out.println(response.toString()); } @Test public void testDeleteUser() { String response = webResource.path("/user/deleteUser/59").delete( String.class); System.out.println(response.toString()); } @Test public void testUpdateUser() { User user = new User(); user.setUsername("王三兒"); user.setPassword("wangsaner"); String response = webResource.path("/user/updateUser/64") .entity(user, MediaType.APPLICATION_JSON).put(String.class); System.out.println(response.toString()); } }七、測試結果如下:
Hibernate: insert into test.user (username, password, address, tel) values (?, ?, ?, ?) {"message":"success"} Hibernate: select user0_.id as id1_2_0_, user0_.username as username2_2_0_, user0_.password as password3_2_0_, user0_.address as address4_2_0_, user0_.tel as tel5_2_0_ from test.user user0_ where user0_.id=? {"message":"fail"} Hibernate: update test.user set username=?, password=?, address=?, tel=? where id=? Hibernate: select user0_.id as id1_2_, user0_.username as username2_2_, user0_.password as password3_2_, user0_.address as address4_2_, user0_.tel as tel5_2_ from test.user user0_ where user0_.username=? and user0_.password=? {"address":"ss","id":48,"password":"1233","tel":"1232333","username":"xx"}
將項目部署到服務器上運行,在Web調試過程中,所有調試一切正常,但是在運行單元測試的時候報如下異常錯誤:
Caused by: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index; at org.hibernate.cfg.annotations.EntityBinder.processComplementaryTableDefinitions(EntityBinder.java:973) at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:824) at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3845) at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3799) at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1412) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850) at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849) at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562) ... 45 more解決辦法:具體原因是因為項目中存在其他版本的JPA實現,導致版本沖突,在調用javax.persistence.*時沖突,如Eclipse link,所以需要在pom.xml中去掉Eclipse 對JPA的支持。