1. 程式人生 > >Spring MVC+Hibernate JPA搭建的博客系統項目中所遇到的坑

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

phoenix min ews googl exc ssl dia one UC

標簽: springmvc hibernate 技術分享圖片 分類:

目錄(?)[+]

項目代碼地址: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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

一開始我是用默認的在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.

技術分享圖片

圖片來自 : http://stackoverflow.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

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