Hibernate 5 Introduction

Hibernate 5 Introduction

Articles Catalogue

Preface

Why do I suddenly think of writing a simple configuration tutorial for hibernate, because I haven't dealt with databases in the last two years, and I didn't know the configuration of these frameworks before, so I want to take the simple hibernate that I used before to be more proficient and impressed. Blog, help others at the same time by leaving some information for future use, while developing a good habit of blogging.

ps: Later, when you have time, you may pass the entire test Demo project on to GitHup (actually, the code is given).

Environmental description

Mysql(windows10)5.7.26,hibernate5.3.10,druid1.1.19,c3p05.3.10

Configuration process

1. Database creation

Create as shown in the figure:

2. Project Construction

This tutorial is based on MySQL 5.7.26 and hibernate 5.3.10. The connection pool uses druid and c3p0 (alternative), but does not use spring. To facilitate the introduction of packages, first build a maven-based web project, and then add the following references to the pom file.

	<properties>
		<!-- version management -->
		<hibernate.version>5.3.10.Final</hibernate.version>
		<c3p0.version>5.3.10.Final</c3p0.version>
		<mysql.version>8.0.16</mysql.version>
		<hibernate.version>5.3.10.Final</hibernate.version>
		<druid.version>1.1.19</druid.version>
		<lombok.version>1.18.8</lombok.version>

		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<!-- c3p0 Connection pool -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-c3p0</artifactId>
			<version>${c3p0.version}</version>
		</dependency>
		<!-- Ali druid Connection pool -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>${druid.version}</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
			<version>${lombok.version}</version>
		</dependency>
	</dependencies>

Look at the engineering structure first.

3. Configure hibernate.cfg.xml

This paper mainly focuses on explaining how to configure annotations (recommendation). Using xml configuration only provides simple configuration for reference.

Configuration of druid connection pool:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!--dataSource for Druid start -->
		<property name="driverClassName">com.mysql.cj.jdbc.Driver</property>
		<property name="url">jdbc:mysql://localhost:3306/hibernatetest?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false</property>
		<property name="username">test</property>
		<property name="password">123456</property>
		<property name="filters">stat</property>
		<property name="initialSize">1</property>
		<property name="maxActive">20</property>
		<property name="minIdle">1</property>
		<property name="maxWait">60000</property>
		<property name="timeBetweenEvictionRunsMillis">60000</property>
		<property name="minEvictableIdleTimeMillis">300000</property>
		<property name="validationQuery">SELECT 1</property>
		<property name="testWhileIdle">true</property>
		<property name="testOnBorrow">false</property>
		<property name="testOnReturn">false</property>
		<property name="poolPreparedStatements">true</property>
		<property name="maxOpenPreparedStatements">20</property>
		<property name="maxPoolPreparedStatementPerConnectionSize">200</property>
     	<property name="asyncInit">true</property>
		<!--dataSource for Druid end -->
		<!--Specify the database name,mysql Low version used hibernate.default_schema Represents the database name  -->
		<property name="hibernate.default_catalog">hibernatetest</property>
		<!-- Designated database dialect -->
		<!--The dialect is used by default. MyISAM engine -->
		<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
		<!--InnoDB -->
		<!--<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> -->

		<!-- display Hibernate Generated by persistence operations SQL -->
		<property name="show_sql">true</property>

		<!-- take SQL The script is formatted and then output -->
		<property name="hibernate.format_sql">true</property>

		<!--custom ConnectionProvider Class name of, This class is used to Hibernate provide JDBC Connect. -->
		<property name="hibernate.connection.provider_class">com.alibaba.druid.support.hibernate.DruidConnectionProvider</property>

		<!-- Test environment usage create/create-drop Formal Environmental Use update/validate -->
		<property name="hbm2ddl.auto">update</property>

		<!-- Use JDBC Connection Check Database Metadata,It is said that the connection pool is used and set tofalse,But the whole testing processtrueperhapsfalseIt's normal, but just in case. -->
		<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>

		<!-- Disable secondary caching -->
		<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

		<!-- Setting transaction isolation level 1 read uncommited 2Read Commited 4Repeatable reading 8Serialization -->
		<property name="hibernate.connection.isolation">4</property>

		<!--List the class names of all persistent classes -->
		<mapping class="com.hibernate.demo.entity.pojo.School" />
		<mapping class="com.hibernate.demo.entity.pojo.Teacher" />

		<!-- Used for Association hbm configuration file -->
		<mapping resource="com/hibernate/demo/entity/User.hbm.xml" />
	</session-factory>
</hibernate-configuration>

Configuration of c3p0 connection pool:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<!--hibernate.It can be omitted. hibernate Judgment,as hibernate.c3p0.max_size Writable c3p0.max_size -->
	<session-factory>
		<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
		<property name="connection.url">jdbc:mysql://localhost:3306/hibernatetest?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false</property>
		<property name="connection.username">test</property>
		<property name="connection.password">123456</property>

		<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
		<!-- Specify the maximum number of connections in the connection pool -->
		<property name="hibernate.c3p0.max_size">20</property>
		<!-- Specify the minimum number of connections in the connection pool -->
		<property name="hibernate.c3p0.min_size">1</property>
		<!-- Specify the connection timeout in the connection pool -->
		<property name="hibernate.c3p0.timeout">5000</property>
		<!-- Specify the maximum number of caches in the connection pool Statement object -->
		<property name="hibernate.c3p0.max_statements">100</property>
		<property name="hibernate.c3p0.idle_test_period">3000</property>
		<property name="hibernate.c3p0.acquire_increment">2</property>
		<property name="hibernate.c3p0.validate">true</property>
		
		<!--Specify the database name,mysql Low version used hibernate.default_schema Represents the database name  -->
		<property name="hibernate.default_catalog">hibernatetest</property>
		
		<!-- Designated database dialect -->
		<!--The dialect is used by default. MyISAM engine-->
		<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
		<!--InnoDB-->
		<!--<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>-->

		<!-- display Hibernate Generated by persistence operations SQL -->
		<property name="show_sql">true</property>
		
		<!-- take SQL The script is formatted and then output -->
		<property name="hibernate.format_sql">true</property>
		
		<!-- Test environment usage create/create-drop Formal Environmental Use update/validate -->
		<property name="hbm2ddl.auto">update</property>
		
		<!-- Use JDBC Connection Check Database Metadata,It is said that the connection pool is used and set tofalse,But the whole testing processtrueperhapsfalseIt's normal, but just in case. -->
		<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
		
		<!-- Disable secondary caching -->
		<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
		
		<!-- Setting transaction isolation level  1 read uncommited  2Read Commited 4Repeatable reading  8Serialization -->
		<property name="hibernate.connection.isolation">4</property>
		
		<!--List the class names of all persistent classes -->
		<mapping class="com.hibernate.demo.entity.pojo.School"/>
		<mapping class="com.hibernate.demo.entity.pojo.Teacher"/>
		
		<!-- Used for Association hbm configuration file -->
		<mapping resource="com/hibernate/demo/entity/User.hbm.xml" /> 
	</session-factory>
</hibernate-configuration>

Here I have to talk about the choice of dialect. In the process of testing, the errors in building tables are too long; max key length is 1000 bytes. The reason for the errors is that the length of id varchar(300) not null specified by the primary key is too long.

Because I created the data path specifying utf8mb4,utf8mb4 characters with a maximum of four bytes per character, 300*4 exceeded the MyISAM engine's primary key length limit, so I changed MyISAM to InnoDB:

If you want to use InnoDB engine, there are two ways:

Mode 1:

Specify the dialect as org.hibernate.dialect.MySQL5InnoDBDialect in hibernate.cfg.xml

Mode 2: If you stick to the dialect of org.hibernate.dialect.MySQL5Dialect, which defaults to the MyISAM engine, you can add the following attributes in src/resources/hibernate.properties to specify the use of InnoDB engine (tested)

hibernate.dialect.storage_engine=innodb

4. Mapping Relations

There are two ways of mapping hibernate: annotation (recommendation) and xml. I'll configure them here. Of course, XML only provides an entry-level configuration, focusing on annotation configuration. The unit test cases provided later are mainly for annotation classes.

4.1 xml Mapping

User class

package com.hibernate.demo.entity;

import java.util.Date;
import javax.persistence.Entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
	private Integer userId;
	private String firstName;
	private String lastName;
	private String sex;
	private Date birthday;
	private String telNum;
	private Date createTime;

}

The mapping file must be configured in hibernate.cfg.xml to work, as follows:

<mapping resource="com/hibernate/demo/entity/User.hbm.xml"/>

User.hbm.xml mapping file

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<!-- Pay attention to the package name. Write a fully qualified name below if you don't write it. -->
<hibernate-mapping    package="com.hibernate.demo.entity">
 <!-- name Represents the entity class name. table Represents a table name. -->
   <class name="User" table="user">
      <meta attribute="class-description">
         This class contains the user detail. 
      </meta>
      <id name="userId" type="int" column="user_id">
         <generator class="native"/>
         <!-- There are different types of self-growth in different databases with self-growth keys. Baidu can answer the question if necessary.
            <generator class="identity"></generator> -->
      </id>
        <!-- Non-primary key mapping, note that the type is not simple java Type is not a database type, but an intermediate type. Pay attention to case, especially String Start here in lowercase -->
      <property name="firstName" column="first_name" type="string"/>
      <property name="lastName" column="last_name" type="string"/>
      <property name="sex" column="sex" type="string"/>
      <property name="birthday" column="birthday" type="date"/>
      <property name="telNum" column="telNum" type="string"/>
      <property name="createTime" column="createTime" type="timestamp"/>
   </class>
</hibernate-mapping>

4.2 Annotation Mapping

Notes also need to be specified in hibernate.cfg.xml. As follows:

<mapping class="com.hibernate.demo.entity.pojo.Teacher"/>

There is no need to use xml. It's quite convenient. Here's an example. The entity class field has no business meaning. It's just trying to use different annotations, and it's not too much nonsense to go directly to the code.

BaseEntity

package com.hibernate.demo.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;

@MappedSuperclass
public class BaseEntity implements java.io.Serializable {

	/**
	 * <Serial number >
	 */
	private static final long serialVersionUID = 7544096556094410178L;

//  @ Temporal (Temporal Type. DATE) (accurate to date)
//  @ Temporal (Temporal Type. TIME) (accurate to hours and seconds)
//  @ Temporal (Temporal Type. TIMESTAMP) (default year, month, day, hour, second)

	// Record creation time
	@Column(name = "created_time")
	@Temporal(TemporalType.TIMESTAMP)
	private Date createdTime;
	// Record update time
	@Column(name = "updated_time")
	@Temporal(TemporalType.TIMESTAMP)
	private Date updatedTime;
	// Describe the update content
	@Column(name = "body")
	private String description;
	//Annotations are used to support optimistic lock version control.
	@Version
	private Integer version;
	public Date getCreatedTime() {
		return createdTime;
	}
	public void setCreatedTime(Date createdTime) {
		this.createdTime = createdTime;
	}
	public Date getUpdatedTime() {
		return updatedTime;
	}
	public void setUpdatedTime(Date updatedTime) {
		this.updatedTime = updatedTime;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public Integer getVersion() {
		return version;
	}
	public void setVersion(Integer version) {
		this.version = version;
	}
	
}

School

package com.hibernate.demo.entity.pojo;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.hibernate.demo.entity.BaseEntity;

@Entity // Define an entity
@Table(name = "school")
public class School extends BaseEntity{
	private static final long serialVersionUID = 1653242906575651690L;

//	TABLE: Use a specific database table to save the primary key. 
//	SEQUENCE: The primary key is generated from the sequence of the underlying database, provided that the database supports the sequence. 
//	IDENTITY: Primary keys are automatically generated by the database (mainly auto-growing) 
//	AUTO: The primary key is controlled by the program.
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer schoolId;

	@Column(length = 30, nullable = false)
	private String schoolName;
	
	private Long ranking; // ranking
	// Relationships are maintained by Teacher classes
	// Delayed loading
	@OneToMany(mappedBy="schl", fetch=FetchType.LAZY, cascade = CascadeType.ALL, targetEntity = Teacher.class)
	private Set<Teacher> teachers;
	public Integer getSchoolId() {
		return schoolId;
	}
	public void setSchoolId(Integer schoolId) {
		this.schoolId = schoolId;
	}
	public String getSchoolName() {
		return schoolName;
	}
	public void setSchoolName(String schoolName) {
		this.schoolName = schoolName;
	}
	public Long getRanking() {
		return ranking;
	}
	public void setRanking(Long ranking) {
		this.ranking = ranking;
	}
	public Set<Teacher> getTeachers() {
		return teachers;
	}
	public void setTeachers(Set<Teacher> teachers) {
		this.teachers = teachers;
	}
	public School() {
		super();
	}
	
	public School(Integer schoolId, String schoolName, Long ranking, Set<Teacher> teachers) {
		super();
		this.schoolId = schoolId;
		this.schoolName = schoolName;
		this.ranking = ranking;
		this.teachers = teachers;
	}
	@Override
	public String toString() {
		return "School [schoolId=" + schoolId + ", schoolName=" + schoolName + ", ranking=" + ranking + "]";
	}
	
}

Teacher

package com.hibernate.demo.entity.pojo;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;

import com.hibernate.demo.entity.BaseEntity;

@Entity
@Table(name = "teacher")
public class Teacher extends BaseEntity {

	private static final long serialVersionUID = -6858635556382148936L;

	// Primary Key Generation Strategy for Generating UUID
	@Id
	@GenericGenerator(name = "idGenerator", strategy = "org.hibernate.id.UUIDGenerator")
	@GeneratedValue(generator = "idGenerator")
	// Define column names
	// insertable indicates whether the field can appear in the insert statement. The default value is true, and the values of fields such as primary key, timestamp, etc. are usually set to false. Because their values are automatically generated, they do not need to be inserted at insert time.
	@Column(name = "t_id",insertable=false)
	private String teacherId;

	@Type(type = "string")
	private String name;

	@Type(type = "string")
	private String sex;

	/**
	 * fetch: Get the policy when the database object is acquired by session.get():
	 * FetchType.LAZY For lazy loading, this property is acquired the first time it is used, such as calling the getAge() method.
	 * FetchType.EAGER For immediate loading.
	 * optional:Indicates whether the current attribute is optional, defaults to true, and if false, fails when persisted to the database, if null
	 */
	@JoinColumn(name = "s_id")
//	@ManyToOne(fetch = FetchType.EAGER, optional = true,targetEntity = School.class,cascade = CascadeType.ALL)
	@ManyToOne(fetch = FetchType.EAGER, optional = true,targetEntity = School.class,cascade = CascadeType.MERGE)
	@BatchSize(size = 50)
	private School schl;
	
	// Now this property does not want to be generated in the table
	@Transient
	private String msg;

	public String getTeacherId() {
		return teacherId;
	}

	public void setTeacherId(String teacherId) {
		this.teacherId = teacherId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public School getSchl() {
		return schl;
	}

	public void setSchl(School schl) {
		this.schl = schl;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public Teacher() {
		super();
	}

	public Teacher(String teacherId, String name, String sex, School schl, String msg) {
		super();
		this.teacherId = teacherId;
		this.name = name;
		this.sex = sex;
		this.schl = schl;
		this.msg = msg;
	}

	/**
	 *toString Be careful not to export schools, otherwise stack overflow is easily caused by mutual references, where both classes only output common attributes
	 */
	@Override
	public String toString() {
		return "Teacher [teacherId=" + teacherId + ", name=" + name + ", sex=" + sex + ", msg=" + msg + "]";
	}

}

5. Create SessionFactory

package com.hibernate.demo.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class HibernateUtils {
	private static final SessionFactory sessionFactory;
	/* hibernate4.3 Discard the org. hibernate. service. Service Registry Builder class */
	static {
		try {
			/* hibernate5.X Getting factory mode */
			// Mode I
//			sessionFactory = new Configuration().configure().buildSessionFactory();
			// Mode 2
			//  The file name that does not specify the configuration file reads hibernate.cfg.xml by default
			// c3p0
//			StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure("hibernate.cfg_c3p0.xml").build();
			// Default hibernate. cfg. XML Druid
			StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure().build();
			Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder()
					.applyImplicitNamingStrategy(ImplicitNamingStrategyComponentPathImpl.INSTANCE).build();
			// Finally, the session Factory is built using this metadata
			sessionFactory = metadata.getSessionFactoryBuilder().build();
		/**
		 * The following is from the network, not tested, for reference only
		 */
			/*hibernate4.3 Later versions get factory */
//			// The first step is to create a service registration object
//			ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
//					.applySettings(configuration.getProperties()).build();
//			// Step 2 Create Session Factory Objects
//			sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		}catch (Throwable ex) {
			ex.printStackTrace();
			// Log exception!
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static Session getSession() throws HibernateException {
		return sessionFactory.openSession();
	}
}

6. Unit test cases

package com.hibernate.demo.util;

import static org.junit.Assert.assertNotNull;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Root;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.hibernate.demo.entity.pojo.School;
import com.hibernate.demo.entity.pojo.Teacher;

class HibernateUtilsTest {
	private static Session session;
	private static SimpleDateFormat sdf;

	@BeforeAll
	static void setUpBeforeClass() throws Exception {
		sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		session = HibernateUtils.getSession();
	}

	@AfterAll
	static void tearDownAfterClass() throws Exception {
		if(session!=null) {
			session.close();
		}
	}

	@BeforeEach
	void setUp() throws Exception {
	}

	@AfterEach
	void tearDown() throws Exception {
	}

	/**
	 * Increase the number of schools before teachers
	 * @throws Exception 
	 */
	@Test
	void testSave1() throws Exception {
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			School scl1 = new School(null, "Huanggang middle school", 233L,null);
			scl1.setCreatedTime(sdf.parse("1904-12-31 00:00:00"));
			scl1.setUpdatedTime(new Date());
			scl1.setDescription("Description of Huanggang Middle School");
			
			School scl2 = new School(null, "No.1 Middle School Attached to Central China Normal University", 220L,null);
			scl2.setCreatedTime(sdf.parse("1950-9-21 00:00:00"));
			scl2.setUpdatedTime(new Date());
			scl2.setDescription("Description in the First Attachment of Huashi Teachers'College");
			
			Integer id1 = (Integer)session.save(scl1);
			Integer id2 = (Integer)session.save(scl2);
			
			Teacher t1 = new Teacher(null, "Zhang San", "male", scl1, "Zhang San is a PE teacher");
			t1.setCreatedTime(new Date());
			t1.setUpdatedTime(new Date());
			t1.setDescription("Teacher Zhang San's Description");
			session.save(t1);
			
			Teacher t2 = new Teacher("", "Li Si", "female", scl1, "Li Si is a music teacher.");
			t2.setCreatedTime(new Date());
			t2.setUpdatedTime(new Date());
			t2.setDescription("The Description of Teacher Li Si");
			session.save(t2);
			
			Teacher t3 = new Teacher("", "Wang Wu", "male", scl2, "Wang Wu is a chemistry teacher.");
			t3.setCreatedTime(new Date());
			t3.setUpdatedTime(new Date());
			t3.setDescription("Mr. Wang Wu's Description");
			session.save(t3);
			
			tx.commit();
			System.out.println("Huanggang Middle School Record Key:"+id1+"\r\n Record the main keys in the attached middle school of Huashi 1:"+id2);
		} catch (HibernateException e) {
			if (tx != null){
				tx.rollback();
			}
			e.printStackTrace();
		}
	}
	/**
	 * Increase the number of teachers before the number of schools
	 */
	@Test
	void testSave2() {
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			School scl = new School(null, "XX high school", 1L,null);
			scl.setCreatedTime(new Date());
			scl.setCreatedTime(new Date());
			scl.setUpdatedTime(new Date());
			scl.setDescription("XX Description of High School");
			// Relationships are maintained by Teacher. Setting the teacher class cascade = CascadeType.ALL prevents scl objects from being transient and failing to save errors.
			// Or session.persist(scl);
			session.persist(scl);
			Teacher t1 = new Teacher("", "Zhao Liu", "Unknown", scl, "Teacher Zhao Six's Notes");
			t1.setCreatedTime(new Date());
			t1.setUpdatedTime(new Date());
			t1.setDescription("Description of Teacher Zhao Liu");
			session.save(t1);
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null){
				tx.rollback();
			}
			e.printStackTrace();
		}
	}

	
	@Test
	public void deleteTeacher() {
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			String hql = "from Teacher t where t.name = ?1";
			Query<?> query = session.createQuery(hql);
			query.setParameter(1,"Zhao Liu");
			@SuppressWarnings("unchecked")
			List<Teacher> list = (List<Teacher>) query.list();
	        for (Teacher tec : list) {
	        	String teacherId = tec.getTeacherId();
	        	Integer schoolId = tec.getSchl().getSchoolId();
	        	assertNotNull(teacherId);
	        	session.delete(tec);
	        	// If the Teacher class is set to CascadeType.ALL, it detects that the school will be cascaded, so set CascadeType.MERGE here.
	        	School school = session.get(School.class, schoolId);
	        	System.out.println(school);
	        }
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		}
	}
	
	@Test
	public void findAll() {
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			List<?> employees = session.createQuery("FROM School").list();
			for (Iterator<?> iterator = employees.iterator(); iterator.hasNext();) {
				School sc = (School) iterator.next();
				System.out.print("School Name: " + sc.getSchoolName());
				// Because it is lazy loading, the teacher information is not queried until the next line is executed.
				// Generally, one-to-many fetch = FetchType.LAZY on one side can improve efficiency.
				Set<Teacher> teachers = sc.getTeachers();
				if(teachers == null) {
					System.out.println(sc);
				}
				System.out.println("Total number of school teachers:"+teachers.size());
			}
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null){
				tx.rollback();
			}
			e.printStackTrace();
		}
	}
 
	@Test
	public void queryByHQL() {
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			String hql = "from School s order by s.ranking desc";
			Query<School> query = session.createQuery(hql, School.class);
			//Specifies that the query starts from that object, and the index position of the parameter starts from 0.
			query.setFirstResult(0);
			//The maximum number of objects to be searched at a time when paging
			query.setMaxResults(1);
			List<School> list = query.getResultList();
			for (School s : list) {
				System.out.println(s.getSchoolName());
			}
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		}
	}
	@Test
	public void queryByQBC() {
		Transaction tx = null;
		try {
			tx = session.beginTransaction();

			CriteriaBuilder builder = session.getCriteriaBuilder();
			CriteriaQuery<School> criteria = builder.createQuery(School.class);
			Root<School> from = criteria.from(School.class);
			Order order = builder.desc(from.get("ranking"));
            criteria.orderBy(order);
            Query<School> query = session.createQuery(criteria); 
			//Specifies that the query starts from that object, and the index position of the parameter starts from 0.
			query.setFirstResult(0);
			//The maximum number of objects to be searched at a time when paging
			query.setMaxResults(1);
			List<School> list = query.getResultList();
			for (School s : list) {
				System.out.println(s.getSchoolName());
			}
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		}
	}

	
	@Test
	public void deleteSchool() {
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			School school = session.get(School.class, 5);
			if(school!=null) {
				session.delete(school);
			}
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		}
	
	}
}

summary

Because the hibernate version used is newer, and some different settings have been tried in the process, in short, all kinds of twists and turns. There are few related materials on the Internet and they can't solve the problem. In the end, debug step by step and keep trying to complete this blog. Generally speaking, it's still very fruitful. After all, many things were not even half-understood before, but now the whole environment has been tested once, and the understanding of the whole hibernate has been deepened a lot. The first time to write this official blog in markdown format, it may be unsatisfactory in typesetting. If there is something wrong in the text, I hope you will not hesitate to give advice.

Keywords: Hibernate Session xml Database

Added by freedmania on Sat, 10 Aug 2019 17:22:30 +0300