Code ví dụ Hibernate @OneToOne – Quan hệ một – một.
(Xem thêm: Hướng dẫn tự học Hibernate)
Quan hệ 1-1 được dùng cho những trường hợp một bản ghi chỉ cho phép duy nhất một bản ghi khác tham chiếu tới nó.
(Xem thêm: Sự khác nhau giữa @OneToOne
với @ManyToOne
trong Hibernate)
Ví dụ 1: Trường hợp thừa kế, Student extends Person
Một bản ghi person
chỉ được tham chiếu bởi 1 bản ghi student
Ví dụ 2: Trường hợp sử dụng chung id, 1 bản ghi item
chỉ được tham chiếu bởi 1 bản ghi item_detail
, item
và item_detail
sẽ có chung giá trị id
Trong bài này mình sẽ thực hiện viết code ví dụ cho ví dụ 1.
Tạo database
CREATE SCHEMA `hibernate-demo-6` ; CREATE TABLE `hibernate-demo-6`.`person` ( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(45) NULL, `address` VARCHAR(45) NULL, PRIMARY KEY (`id`)); CREATE TABLE `hibernate-demo-6`.`student` ( `id` INT NOT NULL AUTO_INCREMENT, `class_name` VARCHAR(45) NULL, `school_name` VARCHAR(45) NULL, `person_id` INT NULL, PRIMARY KEY (`id`), UNIQUE INDEX `person_id_UNIQUE` (`person_id` ASC), CONSTRAINT `student-person` FOREIGN KEY (`person_id`) REFERENCES `hibernate-demo-6`.`person` (`id`));
Các bạn để ý, person_id
sẽ là UNIQUE
vì mỗi student
sẽ tham chiếu tới 1 person
riêng biệt nên chúng sẽ không được trùng nhau.
Các công nghệ sử dụng:
Cấu trúc project
Các thư viện sử dụng
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>stackjava.com</groupId> <artifactId>HibernateOneToOneExample</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <hibernate.version>5.3.6.Final</hibernate.version> </properties> <dependencies> <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> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> </dependencies> </project>
Cấu hình hibernate, kết nối MySQL
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="persistence"> <description>Demo Hibernate OneToOne</description> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hibernate-demo-6" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="admin1234" /> <property name="hibernate.show_sql" value="true" /> </properties> </persistence-unit> </persistence>
Trong ví dụ này mình sử dụng entityManager
nên sẽ khai báo file persistence.xml
nếu các bạn sử dụng hibernateSession
thì có thể khai báo file hibernate.cfg.xml
(Xem lại: Code ví dụ Hibernate EntityManager, EntityManagerFactory)
Các file entities
package stackjava.com.hibernatedemo.entities; import javax.persistence.*; @Entity @Table(name = "person") public class Person { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "name") private String name; @Column(name = "address") private String address; @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", address=" + address + "]"; } // getter - setter }
package stackjava.com.hibernatedemo.entities; import javax.persistence.*; @Entity @Table(name = "student") public class Student { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "class_name") private String className; @Column(name = "school_name") private String schoolName; @OneToOne @JoinColumn(name = "person_id", nullable = false) private Person person; @Override public String toString() { return "Student [id=" + id + ", className=" + className + ", schoolName=" + schoolName + "]"; } // setter - getter }
- Annotation
@OneToOne
biểu thị mối quan hệ 1 – 1 @JoinColumn(name = "person_id")
biểu thị rằng 2 đối tượng mapping qua columnperson_id
Trường hợp dùng chung id thì ta thay bằng annotation@PrimaryKeyJoinColumn
Demo 1
Insert 1 đối tượng person và 1 đối tượng student.
package stackjava.com.hibernatedemo; import javax.persistence.*; import stackjava.com.hibernatedemo.entities.*; public class DemoInsert { public static void main(String[] args) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); Person person = new Person("kai", "ha noi - viet nam"); Student student = new Student("D11CN2", "PTIT"); student.setPerson(person); entityManager.persist(person); entityManager.persist(student); // Student student2 = new Student("DXXXX1", "FTU"); // student2.setPerson(person); // entityManager.persist(student2); entityManager.getTransaction().commit(); System.out.println("--------- after insert -------------"); System.out.println(person); System.out.println(student); entityManager.close(); entityManagerFactory.close(); } }
Kết quả:
Hibernate: insert into person (address, name) values (?, ?) Hibernate: insert into student (class_name, person_id, school_name) values (?, ?, ?) --------- after insert ------------- Person [id=1, name=kai, address=ha noi - viet nam] Student [id=1, className=D11CN2, schoolName=PTIT]
Trong class trên, nếu bạn comment phần tạo và insert student2
nó sẽ xảy ra lỗi ConstraintViolationException
ví có tới 2 đối tượng student
tham chiếu tới 1 đối tượng person
Demo 2
Select đối tượng 1-1
package stackjava.com.hibernatedemo; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import stackjava.com.hibernatedemo.entities.Student; public class DemoSelect { public static void main(String[] args) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); Student student= entityManager.find(Student.class, 1); System.out.println(student); System.out.println(student.getPerson()); entityManager.getTransaction().commit(); entityManager.close(); entityManagerFactory.close(); } }
Kết quả:
Hibernate: select student0_.id as id1_1_0_, student0_.class_name as class_na2_1_0_, student0_.person_id as person_i4_1_0_, student0_.school_name as school_n3_1_0_, person1_.id as id1_0_1_, person1_.address as address2_0_1_, person1_.name as name3_0_1_ from student student0_ inner join person person1_ on student0_.person_id=person1_.id where student0_.id=? Student [id=1, className=D11CN2, schoolName=PTIT] Person [id=1, name=kai, address=ha noi - viet nam]
Okay, Done!
Download code ví dụ trên tại đây.
References: