标签: hibernate

  • 创建一个基于SpringBoot2.1.x的JavaFX程序

    1.创建SpringBoot项目

    到 https://start.spring.io/ 创建一个SpringBoot2.1.x项目,解压后使用MyEclipse2015导入为maven项目~

    2.引入JavaFX

    对SpringBoot入口程序Application进行改造,继承javafx的application类,并引入接口CommandLineRunner, Consumer<Stage>,接着加入如下代码(高亮部分):

    package com.dgzq;
    
    import java.util.function.Consumer;
    
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.scene.Scene;
    import javafx.scene.control.Tab;
    import javafx.scene.control.TabPane;
    import javafx.scene.control.TabPane.TabClosingPolicy;
    import javafx.stage.Stage;
    
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class DgzqApplication extends Application implements CommandLineRunner, Consumer<Stage>{
    
    	public static void main(String[] args) {
    		SpringApplication.run(DgzqApplication.class, args);
    	}
    	
    	@Override
    	public void run(String... args) throws Exception {
    		
    		Platform.runLater(new Runnable() {
    		    @Override
    		    public void run() {
    		    	
    		    	Stage stage = new Stage();
            		
    		    	try {
    					start(stage);
    				} catch (Exception e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
            		
    		    }
    		});
    		
    	}
    
    	@Override
    	public void start(Stage primaryStage) throws Exception {
    		accept(primaryStage);
    	}
    
    	@Override
    	public void accept(Stage stage) {
    		
    		TabPane tabPane = new TabPane();	//增加标签面板
    		tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
    		
    		Scene scene = new Scene(tabPane, 900, 690);
    		stage.setScene(scene);
    		stage.setTitle("测试界面");
    		
    		Tab tab1 = new Tab("标签页1");
    		Tab tab2 = new Tab("标签页2");
    		tabPane.getTabs().addAll(tab1,tab2);
    		tabPane.getSelectionModel().select(tab1);	//设置默认选中
    		
    		stage.show();
    	}
    
    }
    

    然后启动,出现如下界面则为成功:

    ac571e727fe9d73b3500c54a3e2117c

     

    3.增加预加载页面

    在pom.xml加入如下依赖:

    		<!-- SpringBoot2.x与JavaFX的集成 -->
    		<!-- https://mvnrepository.com/artifact/de.roskenet/springboot-javafx-support -->
    		<dependency>
    		    <groupId>de.roskenet</groupId>
    		    <artifactId>springboot-javafx-support</artifactId>
    		    <version>2.1.6</version>
    		</dependency>

     

    新增一个启动入口文件如MainApplication.java用于展示欢迎界面,代码如下:

    package com.dgzq;
    
    import java.io.File;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import de.felixroske.jfxsupport.AbstractJavaFxApplicationSupport;
    import de.felixroske.jfxsupport.SplashScreen;
    import javafx.scene.Scene;
    import javafx.scene.control.Alert;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
    import javafx.scene.paint.Color;
    
    @SpringBootApplication
    public class MainApplication extends AbstractJavaFxApplicationSupport {
    	
    	public static SplashScreen splashScreen;
    	public static Stage splashStage;
    	public static Scene splashScene;
    	
        public static void main(String[] args) {
        	
        	//启动(若需要以fxml形式展示主界面,则第二个传参可以为"MainStageView.class"之类的)
        	launch(MainApplication.class, null, args);
            
        }
    
        @Override
        public void start(Stage stage) throws Exception {
    
        	MainApplication.splashScreen = new SplashScreen();
        	MainApplication.splashStage = new Stage(StageStyle.TRANSPARENT);
        	MainApplication.splashScene = new Scene(splashScreen.getParent(), Color.TRANSPARENT);
        	MainApplication.splashStage.setScene(splashScene);
        	MainApplication.splashStage.initStyle(StageStyle.TRANSPARENT);
        	MainApplication.splashStage.show();
    
        }
        
    }

    在预加载完成后还要再正式界面中隐藏掉本界面,因此要在原来的application类的stage.show()前面加入如下代码:

    MainApplication.splashStage.hide();
    MainApplication.splashStage.setScene(null);

    然后注释掉原来的application启动类中的main方法:

    /*public static void main(String[] args) {
    	SpringApplication.run(DgzqApplication.class, args);
    }*/

    最后启动刚刚新建的MainApplication.java,便会出现中间界面:

    d294a0cca4b571832aaa7b9c70f8363

    好了,大功告成。如果还需要引入sqlite数据库,则可以继续往下操作。

    4.引入hibernate并使用sqlite数据库

    在MainApplication中的 下方加入如下代码,以提示sqlite是否存在:

        	File databaseFile = new File("sqlite3.db");
        	if(!databaseFile.exists()){
    	    	Alert alert = new Alert(Alert.AlertType.INFORMATION);
    			alert.setTitle("错误");
    			alert.setHeaderText(null);
    			alert.setContentText("找不到数据库文件:sqlite3.db(本次运行将自动创建全新的空白数据库)");
    			alert.showAndWait();
        	}

    再pom.xml中加入如下依赖:

    	<!-- sqlite3驱动包 -->
            <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
    		<dependency>
    		    <groupId>org.xerial</groupId>
    		    <artifactId>sqlite-jdbc</artifactId>
    		    <version>3.28.0</version>
    		</dependency>
    		
    		<!-- SpringBoot与hibernate的集成配置 -->
    		<dependency>
    		    <groupId>org.springframework.boot</groupId>
    		    <artifactId>spring-boot-starter-data-jpa</artifactId>
    		</dependency>
    		<!-- SpringBoot使用Hibernate的SessionFactory -->
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-core</artifactId>
    		    <version>5.0.12.Final</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-entitymanager</artifactId>
    		    <version>5.0.12.Final</version>
    		</dependency>
    		
    		<!-- SpringBoot2.x与JavaFX的集成 -->
    		<!-- https://mvnrepository.com/artifact/de.roskenet/springboot-javafx-support -->
    		<dependency>
    		    <groupId>de.roskenet</groupId>
    		    <artifactId>springboot-javafx-support</artifactId>
    		    <version>2.1.6</version>
    		</dependency>

     

    对原来的Application进行修改(加入高亮部分):

    package com.dgzq;
    
    import java.util.function.Consumer;
    
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.scene.Scene;
    import javafx.scene.control.Tab;
    import javafx.scene.control.TabPane;
    import javafx.scene.control.TabPane.TabClosingPolicy;
    import javafx.stage.Stage;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean;
    
    @SpringBootApplication
    public class DgzqApplication extends Application implements CommandLineRunner, Consumer<Stage>{
    	
    	public static SessionFactory sessionFactory;
    	@Autowired
    	public void setSessionFactory(SessionFactory sessionFactory) {
    		DgzqApplication.sessionFactory = sessionFactory;
    	}
    	
    	@Bean
        public HibernateJpaSessionFactoryBean sessionFactory() {
            return new HibernateJpaSessionFactoryBean();
        }
    
    	/*public static void main(String[] args) {
    		SpringApplication.run(DgzqApplication.class, args);
    	}*/
    	
    	@Override
    	public void run(String... args) throws Exception {
    		
    		Platform.runLater(new Runnable() {
    		    @Override
    		    public void run() {
    		    	
    		    	Stage stage = new Stage();
            		
    		    	try {
    					start(stage);
    				} catch (Exception e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
            		
    		    }
    		});
    		
    	}
    
    	@Override
    	public void start(Stage primaryStage) throws Exception {
    		accept(primaryStage);
    	}
    
    	@Override
    	public void accept(Stage stage) {
    		
    		System.out.println("MainJavaFxApplication被实例化了");
    		System.out.println("MainJavaFxApplication.sessionFactory = "+sessionFactory);
    		
    		TabPane tabPane = new TabPane();	//增加标签面板
    		tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
    		
    		Scene scene = new Scene(tabPane, 900, 690);
    		stage.setScene(scene);
    		stage.setTitle("测试界面");
    		
    		Tab tab1 = new Tab("标签页1");
    		Tab tab2 = new Tab("标签页2");
    		tabPane.getTabs().addAll(tab1,tab2);
    		tabPane.getSelectionModel().select(tab1);	//设置默认选中
    		
    		MainApplication.splashStage.hide();
    		MainApplication.splashStage.setScene(null);
    		
    		stage.show();
    	}
    
    }
    

    增加sqlite的方言类SQLiteDialect.java:

    package com.fenji;
    
    import java.sql.Types;
    
    import org.hibernate.dialect.Dialect;
    import org.hibernate.dialect.function.StandardSQLFunction;
    import org.hibernate.dialect.function.SQLFunctionTemplate;
    import org.hibernate.dialect.function.VarArgsSQLFunction;
    import org.hibernate.type.StandardBasicTypes;
    
    public class SQLiteDialect extends Dialect {
        public SQLiteDialect() {
            super();
            registerColumnType(Types.BIT, "integer");
            registerColumnType(Types.TINYINT, "tinyint");
            registerColumnType(Types.SMALLINT, "smallint");
            registerColumnType(Types.INTEGER, "integer");
            registerColumnType(Types.BIGINT, "bigint");
            registerColumnType(Types.FLOAT, "float");
            registerColumnType(Types.REAL, "real");
            registerColumnType(Types.DOUBLE, "double");
            registerColumnType(Types.NUMERIC, "numeric");
            registerColumnType(Types.DECIMAL, "decimal");
            registerColumnType(Types.CHAR, "char");
            registerColumnType(Types.VARCHAR, "varchar");
            registerColumnType(Types.LONGVARCHAR, "longvarchar");
            registerColumnType(Types.DATE, "date");
            registerColumnType(Types.TIME, "time");
            registerColumnType(Types.TIMESTAMP, "timestamp");
            registerColumnType(Types.BINARY, "blob");
            registerColumnType(Types.VARBINARY, "blob");
            registerColumnType(Types.LONGVARBINARY, "blob");
            // registerColumnType(Types.NULL, "null");
            registerColumnType(Types.BLOB, "blob");
            registerColumnType(Types.CLOB, "clob");
            registerColumnType(Types.BOOLEAN, "integer");
    
            registerFunction("concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", ""));
            registerFunction("mod", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "?1 % ?2"));
            registerFunction("substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING));
            registerFunction("substring", new StandardSQLFunction("substr", StandardBasicTypes.STRING));
        }
    
        public boolean supportsIdentityColumns() {
            return true;
        }
    
        public boolean hasDataTypeInIdentityColumn() {
            return false;
        }
    
        public String getIdentityColumnString() {
            return "integer";
        }
    
        public String getIdentitySelectString() {
            return "select last_insert_rowid()";
        }
    
        public boolean supportsLimit() {
            return true;
        }
    
        public String getLimitString(String query, boolean hasOffset) {
            return new StringBuffer(query.length() + 20).append(query).append(hasOffset ? " limit ? offset ?" : " limit ?")
                    .toString();
        }
    
        public boolean supportsTemporaryTables() {
            return true;
        }
    
        public String getCreateTemporaryTableString() {
            return "create temporary table if not exists";
        }
    
        public boolean dropTemporaryTableAfterUse() {
            return false;
        }
    
        public boolean supportsCurrentTimestampSelection() {
            return true;
        }
    
        public boolean isCurrentTimestampSelectStringCallable() {
            return false;
        }
    
        public String getCurrentTimestampSelectString() {
            return "select current_timestamp";
        }
    
        public boolean supportsUnionAll() {
            return true;
        }
    
        public boolean hasAlterTable() {
            return false;
        }
    
        public boolean dropConstraints() {
            return false;
        }
    
        public String getAddColumnString() {
            return "add column";
        }
    
        public String getForUpdateString() {
            return "";
        }
    
        public boolean supportsOuterJoinForUpdate() {
            return false;
        }
    
        public String getDropForeignKeyString() {
            throw new UnsupportedOperationException("No drop foreign key syntax supported by SQLiteDialect");
        }
    
        public String getAddForeignKeyConstraintString(String constraintName, String[] foreignKey, String referencedTable,
                String[] primaryKey, boolean referencesPrimaryKey) {
            throw new UnsupportedOperationException("No add foreign key syntax supported by SQLiteDialect");
        }
    
        public String getAddPrimaryKeyConstraintString(String constraintName) {
            throw new UnsupportedOperationException("No add primary key syntax supported by SQLiteDialect");
        }
    
        public boolean supportsIfExistsBeforeTableName() {
            return true;
        }
    
        public boolean supportsCascadeDelete() {
            return false;
        }
    
        @Override
        public boolean bindLimitParametersInReverseOrder() {
            return true;
        }
    }

    增加配置文件application.properties用于配置数据库(注意高亮行,要指向刚刚创建的方言类SQLiteDialect.java):

    spring.datasource.driver-class-name=org.sqlite.JDBC
    spring.datasource.url=jdbc:sqlite:sqlite3.db
    
    # Specify the DBMS
    #spring.jpa.database=SQLite
    # Show or not log for each sql query
    spring.jpa.show-sql=true
    # Hibernate ddl auto (create, create-drop, update)
    spring.jpa.hibernate.ddl-auto=update
    # Naming strategy
    spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
    # stripped before adding them to the entity manager
    #spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
    spring.jpa.properties.hibernate.dialect=com.dgzq.SQLiteDialect
    # table column upcase problem
    spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
    spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    # auto inject sessionFactory bean
    spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

    好了,运行MainApplication看看效果:

    639fccfb32a10d16ee5a29089e0094f

    如图所示,输入sessionFactory不为空,则注入成功,后面大家自由发挥吧!

    5.补充:记得指定maven打包时的启动入口

    在pom.xml中加入如下高亮代码

    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    				<configuration>
    					<mainClass>com.dgzq.MainApplication</mainClass>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>

    大功告成!

  • 关于Spring+Hibernate时,packagesToScan无法扫描到jar中实体类的解决办法

    由于要做分布式,因此不同的微服务中会用到相同的实体类,因此需要将实体类拿到独立的项目中去,然后生成为jar来被不同的项目引用。

    但是问题来了,当我使用MyEclipse进行Export导出成jar,然后由其他微服务引用此jar时,发现hibernate并没有扫描到jar中的实体类。

    于是我翻了好多资料,找到以下两种解决办法:

    第一种:在配置文件中指定jar中的注解实体类

    		<!-- 手动加载类映射文件(如果类在jar包中,则需要使用这种方式引入才会有有效) -->
    		<property name="annotatedClasses">
    			<list>
    				<value>com.zero4j.model.test.Test</value>
    			</list>
    		</property>

    但是这样做有个缺点,就是无法使用“*”号来进行通配,所以当你有十个类的时候,list中就得有十个value。

    第二种(推荐):使用MyEclipse导出公共实体类时,要勾选“Add directory entiriess”

    49f3fe9dd03935ab16bbeaa65c80b51

    然后在需要引入该jar的项目中重新引入即可。

    原因分析:

    默认方式生成的jar包中,只含有class文件,而并没有我们大众所知的文件夹目录结构。可能我们大多数人认为com.test.Student类,Student类文件就应该在com文件夹下的test文件夹里,这其实是片面的,是一个误区!

    com.test真正的含义是package包域名,就好比.net里的命名空间,它只是为了区分、汇总、唯一标识不同的类而提出的概念,跟文件夹目录层次结构是两回事,我们只是习惯上用文件夹目录来展示package而已。但package却不一定非要用过文件夹目录来展示。

    我们可以用下面这段代码来进一步说明这个问题:

    	public static void main(String[] args) throws Exception {
    		// 项目中jar包所在物理路径
    		String jarName = "E:/Work/stsf_skisok_product/WebRoot/WEB-INF/lib/testpackage.jar";
    		JarFile jarFile = new JarFile(jarName);
    		Enumeration<JarEntry> entrys = jarFile.entries();
    		while (entrys.hasMoreElements()) {
    			JarEntry jarEntry = entrys.nextElement();
    			System.out.println(jarEntry.getName());
    		}				
    	}

    默认生成的jar包,运行结果如下:

    META-INF/MANIFEST.MF
    com/wang/util/DateStyle.class
    com/wang/util/PropertiesUtil$1.class
    com/wang/util/PropertiesUtil.class
    com/wang/util/Week.class
    com/wang/util/DateUtil.class
    com/wang/vo/request/hotel/test/PopularCityRequest.class
    com/wang/vo/request/hotel/test/EconomicsRequest.class
    com/wang/vo/request/hotel/test/HotelProductVouchRequest.class
    com/wang/vo/request/hotel/test/QueryOrderListRequest.class
    com/wang/vo/request/hotel/test/HotelListQueryRequest.class
    com/wang/vo/request/hotel/test/RoomReserveRequest.class
    com/wang/vo/request/hotel/test/HotelOneQueryRequest.class
    com/wang/vo/request/hotel/test/HotelBrandRequest.class

    如果勾选Add directory entries选项生成的jar包,运行结果如下:

    META-INF/MANIFEST.MF
    com/
    com/wang/
    com/wang/util/
    com/wang/util/DateStyle.class
    com/wang/util/PropertiesUtil$1.class
    com/wang/util/PropertiesUtil.class
    com/wang/util/Week.class
    com/wang/util/DateUtil.class
    com/wang/vo/
    com/wang/vo/request/
    com/wang/vo/request/hotel/
    com/wang/vo/request/hotel/test/
    com/wang/vo/request/hotel/test/PopularCityRequest.class
    com/wang/vo/request/hotel/test/EconomicsRequest.class
    com/wang/vo/request/hotel/test/HotelProductVouchRequest.class
    com/wang/vo/request/hotel/test/QueryOrderListRequest.class
    com/wang/vo/request/hotel/test/HotelListQueryRequest.class
    com/wang/vo/request/hotel/test/RoomReserveRequest.class
    com/wang/vo/request/hotel/test/HotelOneQueryRequest.class
    com/wang/vo/request/hotel/test/HotelBrandRequest.class

    这样也就解释了为何打成jar包后用getResource获取资源url总是为空的原因了。

  • SpringBoot2.1.1整合hibernate5.0.12使用SessionFactory

    1、在pom.xml中加入如下依赖:

    		<!-- Spring的aspect切面支持 -->
    		<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-aspects</artifactId>
    		    <version>4.2.5.RELEASE</version>
    		</dependency>
    
    		<!-- Spring的ORM(Hibernate)映射支持 -->
    		<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-orm</artifactId>
    		    <!-- <version>5.0.12.RELEASE</version>
    		    <version>4.3.11.RELEASE</version> -->
    		    <version>4.2.5.RELEASE</version>
    		</dependency>
    
    		<!-- Spring对Hibernate-SessionFactory的事务管理支持 -->
    		<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-core</artifactId>
    		    <version>5.0.12.Final</version>
    		</dependency>
    
    		<!-- mysql连接驱动 -->    
    		<dependency>    
    			<groupId>mysql</groupId>    
    			<artifactId>mysql-connector-java</artifactId>    
    			<version>5.1.9</version>
    		</dependency>

    如果pom.xml中有如下jpa依赖,记得清注释以下内容:

    		<!-- SpringBoot对JPA的支持 -->
    		<!-- <dependency>
    		    <groupId>org.springframework.boot</groupId>
    		    <artifactId>spring-boot-starter-data-jpa</artifactId>
    		</dependency> -->

    如果出现FilterRegistrationBean报错,则意味着缺少SpringMVC的filter依赖,办法之一是引入含有该filter的依赖(eureka的server依赖也是包含的):

    		<!-- SpringMVC的配置 -->
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    	        	<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>

     

    2、在application.properties中加入如下配置:

    #mysql
    spring.datasource.url=jdbc\:mysql\://localhost\:3306/xxxxx?useSSL\=false&characterEncoding\=utf8
    spring.datasource.username=root
    spring.datasource.password=
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver

    如果在低版本SpringBoot中进行配置,则可能会遇到错误“Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true”,此时则需要在application.properties补充配置:

    spring.main.allow-bean-definition-overriding=true

    因为SpringBoot的SessionFactory会自动注入默认的Transactional事务管理器,但这个事务管理器搭配hibernate的SessionFactory会出现数据库连接池线程卡死的问题,即假如配置线程池的连接数为10,一旦连接数大于10,则线程池会出现卡死的情况,因此我们需要自行配置hibernate的事务管理器来覆盖SpringBoot原有的Transactional事务管理器。

    3、在SpringBoot的启动入口类上加入注解@ImportResource(“classpath:hibernate.xml”):

    @SpringBootApplication
    @ImportResource("classpath:hibernate.xml")
    public class xxxxxApplication extends SpringBootServletInitializer{
    
    	public static void main(String[] args) {
    		SpringApplication.run(xxxxxApplication.class, args);
    	}
    
    }

    4、在resources目录中加入配置文件hibernate.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:jee="http://www.springframework.org/schema/jee"
    	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
    	xmlns:tool="http://www.springframework.org/schema/tool" xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/tx
               http://www.springframework.org/schema/tx/spring-tx.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop.xsd
               http://www.springframework.org/schema/jee
               http://www.springframework.org/schema/jee/spring-jee.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd
               http://www.springframework.org/schema/util
               http://www.springframework.org/schema/util/spring-util.xsd
               http://www.springframework.org/schema/tool
               http://www.springframework.org/schema/tool/spring-tool.xsd"
        default-autowire="no">
    	
    	<!-- hibernate sessionFactory 创建 -->
    	<!-- hibernate.cfg.xml Spring config -->
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    		<!-- connection -->
    		<property name="dataSource">
    			<ref bean="dataSource" />
    		</property>
    		<!-- hibernate 类文件配置 -->
    		<!-- hibernate自身属性 -->
    		<property name="hibernateProperties">
    			<props>
    				<!-- 显示Hibernate 持久化操作所生成的SQL -->
    				<prop key="hibernate.show_sql">false</prop>
    				<!-- 将SQL脚本进行格式化后在输出 -->
    				<prop key="hibernate.format_sql">true</prop>
    				<!-- 指定数据库方言 -->
    				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
    				<!-- **************** -->
    				<prop key="hibernate.hbm2ddl.auto">update</prop>
    				<!-- 解决no session found -->
    				<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
    				
    				<!-- <prop key="hibernate.cache.use_second_level_cache">true</prop> -->
    				<!-- hibernate4的二级缓存配置 -->
    				<!-- <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> -->
    				<!-- hibernate3的二级缓存配置 -->
    				<!-- <prop name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> -->
            		<!-- 开启查询缓存 -->
    				<!-- <prop key="hibernate.cache.use_query_cache">true</prop> -->
    				
    			</props>
    		</property>
    		<!-- 自动扫描注解方式配置的hibernate类文件 -->
    		<property name="packagesToScan">
    			<list>
    				<value>com.zero4j.model</value>
    			</list>
    		</property>
    		<!-- 手动加载配置映射文件 -->
    		<property name="mappingResources">
    			<list>
    				<!-- <value>com/***/model/order/Order.hbm.xml</value> -->
    			</list>
    		</property>
    		<!-- 手动加载注解类映射文件-->
    		<!-- <property name="annotatedClasses">
    			<list>
    				<value>com.zero4j.model.test.Test</value>
    			</list>
    		</property> -->
    	</bean>
    
    	<!-- 开启注解事务 只对当前配置文件有效 -->
      	<tx:annotation-driven transaction-manager="txManager"/>
    	<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            	<property name="sessionFactory" ref="sessionFactory"/>
       	</bean>
    
    </beans>
    

    5、增加事务管理配置,有两种方式,一种是使用SpringBoot的config注入方式,另外一种是加在hibernate.xml中。(记住下面5.1和5.2是二选一)

    5.1、使用SpringBoot的confiug注入方式:增加配置文件TransactionAdviceConfig.java:

    package com.isuidian.config;
    
    
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.aop.Advisor;
    import org.springframework.aop.aspectj.AspectJExpressionPointcut;
    import org.springframework.aop.support.DefaultPointcutAdvisor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.TransactionDefinition;
    import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
    import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
    import org.springframework.transaction.interceptor.TransactionInterceptor;
    
    @Aspect
    @Configuration
    public class TransactionAdviceConfig {
    
    	 //使dao使用session
    	private static final String AOP_POINTCUT_EXPRESSION = " (execution(* com..dao..*.*(..))) ";
    	//controller由过滤器中进行设置,这里设置会抽风
    	/*private static final String AOP_POINTCUT_EXPRESSION2 = " (execution(* com..controller..*.*(..))) ";*/
    	 
    	 
        @Autowired
        private PlatformTransactionManager transactionManager;
    
        @Bean
        public TransactionInterceptor txAdvice() {
    
            DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute();
            txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    
            DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute();
            txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
            txAttr_REQUIRED_READONLY.setReadOnly(true);
            
            
            DefaultTransactionAttribute txAttr_READONLY = new DefaultTransactionAttribute();
            txAttr_READONLY.setReadOnly(true);
            
            
    
            NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
    
            source.addTransactionalMethod("save*", txAttr_REQUIRED);
            source.addTransactionalMethod("add*", txAttr_REQUIRED);
            source.addTransactionalMethod("create*", txAttr_REQUIRED);
            source.addTransactionalMethod("insert*", txAttr_REQUIRED);
            source.addTransactionalMethod("update*", txAttr_REQUIRED);
            source.addTransactionalMethod("merge*", txAttr_REQUIRED);
            source.addTransactionalMethod("del*", txAttr_REQUIRED);
            source.addTransactionalMethod("remove*", txAttr_REQUIRED);
            source.addTransactionalMethod("put*", txAttr_REQUIRED);
            source.addTransactionalMethod("use*", txAttr_REQUIRED);
            source.addTransactionalMethod("exec*", txAttr_REQUIRED);
            source.addTransactionalMethod("set*", txAttr_REQUIRED);
            
            
            source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);//特殊,service在save后会重新读取,如果设置成REQUIRED_READONLY,则save不会保存数据
            source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY);
            
            /*
            source.addTransactionalMethod("save*", txAttr_REQUIRED);
            source.addTransactionalMethod("delete*", txAttr_REQUIRED);
            source.addTransactionalMethod("update*", txAttr_REQUIRED);
            source.addTransactionalMethod("exec*", txAttr_REQUIRED);
            source.addTransactionalMethod("set*", txAttr_REQUIRED);
            source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY);
            
            */
            source.addTransactionalMethod("*", txAttr_READONLY);
            return new TransactionInterceptor(transactionManager, source);
        }
    
        @Bean
        public Advisor txAdviceAdvisor() {
            AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
            pointcut.setExpression( AOP_POINTCUT_EXPRESSION );
            return new DefaultPointcutAdvisor(pointcut, txAdvice());
        }
        
       /* @Bean
        public Advisor txAdviceAdvisor2() {
            AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
            pointcut.setExpression( AOP_POINTCUT_EXPRESSION2 );
            return new DefaultPointcutAdvisor(pointcut, txAdvice());
        }*/
    }

    5.2、加在hibernate.xml中:

        <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="save*" propagation="REQUIRED" />
                <tx:method name="add*" propagation="REQUIRED" />
                <tx:method name="create*" propagation="REQUIRED" />
                <tx:method name="insert*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="merge*" propagation="REQUIRED" />
                <tx:method name="del*" propagation="REQUIRED" />
                <tx:method name="remove*" propagation="REQUIRED" />
                <tx:method name="put*" propagation="REQUIRED" />
                <tx:method name="use*" propagation="REQUIRED"/>
                <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->
                <tx:method name="get*" propagation="REQUIRED" read-only="true" />
                <tx:method name="count*" propagation="REQUIRED" read-only="true" />
                <tx:method name="find*" propagation="REQUIRED" read-only="true" />
                <tx:method name="list*" propagation="REQUIRED" read-only="true" />
                <tx:method name="*" read-only="true" />
            </tx:attributes>
        </tx:advice>

     

    6、增加事务管理过滤器FilterConfig.java,自动开启事务管理:

    package com.isuidian.config;
    
    
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.orm.hibernate5.support.OpenSessionInViewFilter;
    
    @Aspect
    @Configuration
    public class FilterConfig {
    
    	//解决调用接口时session抽风的问题
    	@Bean
    	public FilterRegistrationBean<OpenSessionInViewFilter> testFilterRegistration() {	
    		FilterRegistrationBean<OpenSessionInViewFilter> registration = new FilterRegistrationBean<>();
    		registration.setFilter(new OpenSessionInViewFilter());
    		registration.addUrlPatterns("/*");//配置过滤路径
    		return registration;
    	}
    	
    }

    7、搞掂,启动项目!在需要使用SessionFactory的地方使用如下方式注入即可:

    @Autowired
    private SessionFactory sessionFactory;

     

    常见问题

    重复的依赖错误

    错误提示如下:

    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactory' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryBuilder' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactoryBuilder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.NoSuchFieldError: HANA
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:509) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:853) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at com.gushing.GushingApplication.main(GushingApplication.java:29) [classes/:na]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryBuilder' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactoryBuilder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.NoSuchFieldError: HANA
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:509) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:273) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1237) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	... 24 common frames omitted
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.NoSuchFieldError: HANA
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:456) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:273) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1237) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	... 38 common frames omitted
    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.NoSuchFieldError: HANA
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	... 52 common frames omitted
    Caused by: java.lang.NoSuchFieldError: HANA
    	at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.<clinit>(DatabaseLookup.java:56) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:142) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.jpaVendorAdapter(JpaBaseConfiguration.java:112) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$f91d7855.CGLIB$jpaVendorAdapter$4(<generated>) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$f91d7855$$FastClassBySpringCGLIB$$292a616.invoke(<generated>) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$f91d7855.jpaVendorAdapter(<generated>) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	... 53 common frames omitted
    
    

    这很有可能你的依赖中有重复的内容,如:

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

    这个是需要注释掉的,不然会报错。

  • 在SpringBoot中使用SessionFactory的方法

    首先项目中已经使用JPA的方式连接,然后加入hibernate依赖:

    	<properties>
    		<java.version>1.8</java.version>
    		<hibernate.version>5.0.12.Final</hibernate.version>
    	</properties>
    		<!-- SpringBoot使用Hibernate的SessionFactory -->
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-core</artifactId>
    		    <version>${hibernate.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-entitymanager</artifactId>
    		    <version>${hibernate.version}</version>
    		</dependency>

     

    然后有以下几种方式,选择一种合适自己的。

    方法一:

    增加配置文件HibernateConfig.java:

    package com.testSSH.config;
    
    import javax.persistence.EntityManagerFactory;
    
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class HibernateConfig {
        
        @Bean
        public SessionFactory sessionFactory(@Qualifier("entityManagerFactory") EntityManagerFactory emf){
             return emf.unwrap(SessionFactory.class);
         }
    
    }

    如果要使用@Transactional则需要在application.properties中加上:

    spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

     

    方法二:(推荐)

    在SpringBoot的启动类中加上:

    	@Bean
    	public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
    	    return hemf.getSessionFactory();
    	}

    如果要使用@Transactional则需要在application.properties中加上:

    spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

     

     

    方法三:

    在SpringBoot的启动类中加上:

        @Bean
        public HibernateJpaSessionFactoryBean sessionFactory() {
            return new HibernateJpaSessionFactoryBean();
        }

    如果要使用@Transactional则需要在application.properties中加上:

    spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

     

     

    使用方法:

    @Autowired
    private SessionFactory sessionFactory;

     

  • SpringBoot2.0+Hibernate在Controller使用Session并发性能调优

    从SpringBoot2.0开始,其DataSource就交给了Hikari负责。

    对于高并发需求,根据数据库的性能,若然Controller执行时间过长,过多controller正在等待有限的sessionFactory资源,则会造成线程堵塞,引起雪崩。

    需要在springboot的配置中假如如下设置:

    spring.datasource.hikari.minimum-idle=10
    spring.datasource.hikari.maximum-pool-size=50
    spring.datasource.hikari.idle-timeout=20000
    spring.datasource.hikari.connection-timeout=20000

    最主要是maximum-pool-size参数,在不设置的情况下默认是10,所以当用户卡在controller等待使用session资源时,做并发测试的时候就会出现卡死现象,引起雪崩。

    如果controller中关于数据查询的部分的执行时间较长,maximum-pool-size一定要调大,但是这个值越大我猜测就越内存,一定要适当。