Spring MVC+Hibernate JPA搭建的博客系统项目中所遇到的坑

时间:2023-01-02 23:18:46

项目代码地址:https://github.com/zhisheng17/springmvc

如果觉得不错的话,欢迎给个 star , 如果你想完善这个项目的话,你也可以 fork 后修改然后推送给我。

最近在学习 Spring MVC ,其中在做一个简单的博客系统demo,是使用 SpringMVC 集成

Spring Data JPA(由 Hibernate JPA 提供),来进行强大的数据库访问。结果其中遇到的坑不

是一点点啊,我差点崩溃了,其中最大的原因就是由于 Hibernate JPA 中的bug了,反正一开始

还不知道是这个问题,导致折腾了快一天的时间。想想都可怕啊。

mvc-dispatch-servlet.xml代码


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
>


<!--指明 controller 所在包,并扫描其中的注解-->
<context:component-scan base-package="cn.zhisheng.controller"/>

<!-- 静态资源(js、image等)的访问 -->
<mvc:default-servlet-handler/>

<!-- 开启注解 -->
<mvc:annotation-driven/>

<!--ViewResolver 视图解析器-->
<!--用于支持Servlet、JSP视图解析-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>

<!-- 表示JPA Repository所在的包 -->
<jpa:repositories base-package="cn.zhisheng.repository"/>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="defaultPersistenceUnit"/>
<property name="packagesToScan" value="cn.zhisheng.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/springdemo?useSSL=false</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password">root</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.autoReconnect">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="connection.autoReconnectForPools">true</prop>
<prop key="connection.is-connection-validation-required">true</prop>

<prop key="hibernate.c3p0.validate">true</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">600</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.preferredTestQuery">SELECT 1;</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">true</prop>
<prop key="hibernate.c3p0.idle_test_period">3000</prop>
<prop key="javax.persistence.validation.mode">none</prop>
</props>
</property>
</bean>

<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!-- 开启事务管理注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>cn.zhisheng</groupId>
<artifactId>springmvc</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>springmvc Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
<spring.version>4.2.6.RELEASE</spring.version>
<hibernate.version>5.1.0.Final</hibernate.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.1.RELEASE</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${hibernate.version}</version>
</dependency>

<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>


</dependencies>
<build>
<finalName>springmvc</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

一开始我是用默认的在resources文件里面生成了persistence.xml配置文件进行数据库配置的,后来由于用那种方法,碰到的问题有很多,自己搞了好几个个小时都没弄好,只好换种方法,没想到竟然还是这种效果(泪崩),看来是不治标也不治本。

无奈,只好硬刚了,碰到错误,百度+google,看了大量的的解决方法,都是没用,慢慢的我所加的jar包越来越多,用maven管理的依赖的也变得多起来了,但终究是不能够解决问题的。

其实这时我看了这么多的博客和解决方法,我已经知道了是 Hibernate JPA 的bug问题,途中自己也换了一些版本,还是没能解决办法。

最后在吃完完晚饭后,又折腾了*小时,终于找到可靠有用的解决方案了。

运行成功后,我当时就激动起来了。马丹,老子终于将你解决了。

所以在这里立马就将自己这次的血崩历史纪录下来。

下面写下遇到的问题:(其中有些可能还不记得写了)

  • java.lang.ClassNotFoundException: javax.persistence.EntityManager

  • java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;

  • javax.persistence.PersistenceException: No Persistence provider for EntityManager named defaultPersistenceUnit

  • javax.persistence.PersistenceException: No Persistence provider for EntityManager named defaultPersi

  • java.lang.NoClassDefFoundError: org/hibernate/ejb/HibernatePersistence

  • java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

  • java.lang.ClassNotFoundException: org.hibernate.MappingException

  • NoSuchMethodError: javax.persistence.xxx

等,还有几个,忘记了。。

首先通过报错信息可以知道有些是因为jar包的问题,但是并不是光是缺少jar包的问题,很大的原

因就是因为jar包的版本不同,刚好那个jar包又是有问题的(自身有bug)。

就比如错误:

java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;

就是因为JAVAEE6.0中的 javax.persistence.jar与 hibernate4.3.8中的hibernate-jpa-2.1-api-1.0.0.Final.jar冲突

JoinColumn.foreignKey() was introduced with JPA 2.1, which was not implemented by Hibernate 4 until version 4.3. If you’re using an older version of Hibernate 4 then try upgrading to 4.3.x.

If you’re already using Hibernate 4.3 then make sure you’re also using JPA 2.1 to make sure the API and implementation match up.

Spring MVC+Hibernate JPA搭建的博客系统项目中所遇到的坑

图片来自 : http://*.com/questions/24588860/error-javax-persistence-joincolumn-foreignkeyljavax-persistence-foreignkey-wi

I finally solved this similar problem, there was an old version(hibernate-jpa-2.0-api-1.0.0-Final.jar) in my lib folder which I guess has been preventing maven dependency from loading.

So after I manually deleted it and added (hibernate-jpa-2.1-api-1.0.0-Final.jar) everything started to work.

意思大概就是:

因为JAVAEE6.0中的 javax.persistence.jar与 hibernate4.3.8中的hibernate-jpa-2.1-api-1.0.0.Final.jar冲突 ,我们在pom文件下添加依赖后,竟然没发现在 springmvc(项目名称)\target\springmvc(项目名称)\WEB-INF\lib 下看到 javax.persistence.jar 文件,结果竟然在 springmvc\lib下找到他了。

解决办法就是在 pom文件和 mvc-dispatcher-servlet.xml 都配置好的情况下,将 springmvc\lib下的 javax.persistence.jar 删除。

最后再说一句:Though the error drove almost crazy, hold on, you wil get smile ! Fighting