דוגמה למיפוי One to One באמצעות הואיברנייט עם הוספת אנוטציות

היום נבחן את המיפוי מחד למחד ב-Hibernate. נביט בדוגמה למיפוי מחד למחד ב-Hibernate באמצעות הגעה ותצורת XML.

מיפוי מחד למחד ב-Hibernate

ברוב המקרים, טבלאות במסד הנתונים מתייחסות זו לזו. ישנם כמה סוגים של התמקדות – מחד למחד, מחד לרבים ו־רבים לרבים הם ברמה הרחבה. אלה יכולים להתחלק נוסף להתמקדויות חד כיווניות ודו כיווניות. היום נבחן את המימוש של מיפוי מחד למחד ב-Hibernate באמצעות תצורת XML וגם באמצעות תצורת אנוטציה.

דוגמה להגדרת מסד נתונים למיפוי מחד למחד ב-Hibernate

ראשית עלינו להגדיר מיפוי 1:1 בטבלאות מסד נתונים. ניצור שני טבלאות לדוגמה שלנו – עסקאות ולקוחות. שתי הטבלאות הללו יהיו עם מיפוי 1:1. עסקאות תהיה הטבלה הראשית ונשתמש במפתח זר בטבלת לקוחות עבור מיפוי 1:1. אני מספק סקריפט של MySQL, זהו המסד נתונים שאני משתמש בו למדריך זה. אם אתה משתמש במסד נתונים אחר, ודא שתשנה את הסקריפט להתאם.

-- יצירת טבלת עסקאות
CREATE TABLE `Transaction` (
  `txn_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `txn_date` date NOT NULL,
  `txn_total` decimal(10,0) NOT NULL,
  PRIMARY KEY (`txn_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;

-- יצירת טבלת לקוחות
CREATE TABLE `Customer` (
  `txn_id` int(11) unsigned NOT NULL,
  `cust_name` varchar(20) NOT NULL DEFAULT '',
  `cust_email` varchar(20) DEFAULT NULL,
  `cust_address` varchar(50) NOT NULL DEFAULT '',
  PRIMARY KEY (`txn_id`),
  CONSTRAINT `customer_ibfk_1` FOREIGN KEY (`txn_id`) REFERENCES `Transaction` (`txn_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

תרשים יחסי ייצוג (ERD) של המיפוי 1:1 שלמעלה בין הטבלאות נראה כמו בתמונה למטה. הגדרת בסיס הנתונים שלנו מוכנה, בוא נמשיך לדוגמה של Hibernate בפרויקט One to One כעת.

מבנה פרויקט דוגמה למיפוי 1:1 של Hibernate

צור פרויקט Maven פשוט ב-IDE שלך ב-Java, אני משתמש ב- Eclipse. מבנה הפרויקט הסופי שלנו יראה כמו בתמונה שמופיעה למטה. תחילה נסתכל על דוגמת המיפוי של Hibernate One to One המבוססת על XML ואז נממש אותו באמצעות הערות.

תלותי Maven של Hibernate

הקובץ pom.xml הסופי שלנו נראה כמו שמופיע למטה.

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.journaldev.hibernate</groupId>
  <artifactId>HibernateOneToOneMapping</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
  	<dependency>
  		<groupId>org.hibernate</groupId>
  		<artifactId>hibernate-core</artifactId>
  		<version>4.3.5.Final</version>
  	</dependency>
  	<dependency>
  		<groupId>mysql</groupId>
  		<artifactId>mysql-connector-java</artifactId>
  		<version>5.0.5</version>
  	</dependency>
  </dependencies>
</project>

התלות הן רק ל- Hibernate ולנהג Java של MySQL. שים לב שאני משתמש בגרסה האחרונה של Hibernate 4.3.5.Final ולנהג Java של MySQL בהתאם לגרסת שרת בסיס הנתונים של MySQL שלי (5.0.5). Hibernate 4 משתמש ב- JBoss logging והוא מייבא אוטומטית כתלות תלולה. תוכל לאשר זאת בתלותי Maven של הפרויקט. אם אתה משתמש בגרסאות ישנות יותר של Hibernate, עשויים להיות עליך להוסיף תלותי slf4j.

דגמי מודל של Hibernate One to One Mapping

דגמי מודל עבור מיפוי של Hibernate One to One כדי לשקף טבלאות במסד הנתונים היו נראים כמו שמופיע למטה.

package com.journaldev.hibernate.model;

import java.util.Date;

public class Txn {

	private long id;
	private Date date;
	private double total;
	private Customer customer;
	
	@Override
	public String toString(){
		return id+", "+total+", "+customer.getName()+", "+customer.getEmail()+", "+customer.getAddress();
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	public double getTotal() {
		return total;
	}
	public void setTotal(double total) {
		this.total = total;
	}
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
}
package com.journaldev.hibernate.model;

public class Customer {

	private long id;
	private String name;
	private String email;
	private String address;
	
	private Txn txn;
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public Txn getTxn() {
		return txn;
	}
	public void setTxn(Txn txn) {
		this.txn = txn;
	}
	
}

מאחר שאנו משתמשים בהגדרות מבוססות XML למיפוי, המחלקות של הדוגמה לעיל הן פשוטות כמו כיתות POJO או Java Beans עם שיטות getter-setter. אני משתמש בשם הכיתה Txn כדי למנוע בלבול מאחר ש-API של Hibernate יש לו שם כיתה כמו Transaction.

תצורת מיפוי חד-אל-חד ב-Hibernate

בואו ניצור קבצי תצורת מיפוי חד-אל-חד ב-Hibernate עבור טבלאות Txn ו-Customer. txn.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.journaldev.hibernate.model.Txn" table="TRANSACTION" >
		<id name="id" type="long">
			<column name="txn_id" />
			<generator class="identity" />
		</id>
		<property name="date" type="date">
			<column name="txn_date" />
		</property>
		<property name="total" type="double">
			<column name="txn_total" />
		</property>
		<one-to-one name="customer" class="com.journaldev.hibernate.model.Customer"
			cascade="save-update" />
	</class>
	
</hibernate-mapping>

הנקודה החשובה לשים לב אליה למעלה היא האלמנט one-to-one של ה-Hibernate למאפיין הלקוח. customer.hbm.xml

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

	<class name="com.journaldev.hibernate.model.Customer" table="CUSTOMER">
		<id name="id" type="long">
			<column name="txn_id" />
			<generator class="foreign">
				<param name="property">txn</param>
			</generator>
		</id>
		<one-to-one name="txn" class="com.journaldev.hibernate.model.Txn"
			constrained="true"></one-to-one>

		<property name="name" type="string">
			<column name="cust_name"></column>
		</property>
		<property name="email" type="string">
			<column name="cust_email"></column>
		</property>
		<property name="address" type="string">
			<column name="cust_address"></column>
		</property>
	</class>

</hibernate-mapping>

generator class=“foreign” היא החלק החשוב המשמש למימוש מפתח זר של ה-Hibernate.

קובץ התצורה של Hibernate

כאן נמצא קובץ התצורה של Hibernate עבור תצורת המיפוי שמבוססת על XML. hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">pankaj123</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
        <property name="hibernate.connection.username">pankaj</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        
        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.show_sql">true</property>
        
        <mapping resource="txn.hbm.xml"/>
        <mapping resource="customer.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

קובץ התצורה של Hibernate הוא פשוט, הוא מכיל מאפייני חיבור למסד נתונים ומקורות מיפוי של Hibernate.

מומש באמצעות יישום החברה הטכנולוגית Hibernate SessionFactory

כאן נמצא המחלקת עזר ליצירת מופע SessionFactory של החברה הטכנולוגית Hibernate.

package com.journaldev.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {

	private static SessionFactory sessionFactory;
	
	private static SessionFactory buildSessionFactory() {
        try {
            // יצירת מופע SessionFactory מתוך hibernate.cfg.xml
        	Configuration configuration = new Configuration();
        	configuration.configure("hibernate.cfg.xml");
        	System.out.println("Hibernate Configuration loaded");
        	
        	ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        	System.out.println("Hibernate serviceRegistry created");
        	
        	SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        	
            return sessionFactory;
        }
        catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
        }
    }
	
	public static SessionFactory getSessionFactory() {
		if(sessionFactory == null) sessionFactory = buildSessionFactory();
        return sessionFactory;
    }
}

זהו, נכתוב תוכנית בדיקה כדי לבדוק את המיפוי יחס 1:1 של Hibernate על פי תצורת XML.

תוכנית בדיקת תצורת המיפוי החד לאחד של Hibernate על פי XML

בדוגמת הבדיקה של מיפוי החד לאחד של Hibernate, ניצור תחילה אובייקט Txn ונשמור אותו. לאחר שהוא נשמר במסד הנתונים, נשתמש במזהה הנוצר כדי לאחזר את אובייקט ה-Txn ולהדפיס אותו.

package com.journaldev.hibernate.main;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.journaldev.hibernate.model.Customer;
import com.journaldev.hibernate.model.Txn;
import com.journaldev.hibernate.util.HibernateUtil;

public class HibernateOneToOneMain {

	public static void main(String[] args) {
		
		Txn txn = buildDemoTransaction();
		
		SessionFactory sessionFactory = null;
		Session session = null;
		Transaction tx = null;
		try{
		//קבלת Session
		sessionFactory = HibernateUtil.getSessionFactory();
		session = sessionFactory.getCurrentSession();
		System.out.println("Session created");
		//התחלת עסקה
		tx = session.beginTransaction();
		//שמירת אובייקט המודל
		session.save(txn);
		//ביצוע עסקה
		tx.commit();
		System.out.println("Transaction ID="+txn.getId());
		
		//קבלת נתוני העסקה שנשמרו
		printTransactionData(txn.getId(), sessionFactory);
		
		}catch(Exception e){
			System.out.println("Exception occured. "+e.getMessage());
			e.printStackTrace();
		}finally{
			if(!sessionFactory.isClosed()){
				System.out.println("Closing SessionFactory");
				sessionFactory.close();
			}
		}
	}

	private static void printTransactionData(long id, SessionFactory sessionFactory) {
		Session session = null;
		Transaction tx = null;
		try{
			//קבלת Session
			sessionFactory = HibernateUtil.getSessionFactory();
			session = sessionFactory.getCurrentSession();
			//התחלת עסקה
			tx = session.beginTransaction();
			//שמירת אובייקט המודל
			Txn txn = (Txn) session.get(Txn.class, id);
			//ביצוע עסקה
			tx.commit();
			System.out.println("Transaction Details=\n"+txn);
			
			}catch(Exception e){
				System.out.println("Exception occured. "+e.getMessage());
				e.printStackTrace();
			}
	}

	private static Txn buildDemoTransaction() {
		Txn txn = new Txn();
		txn.setDate(new Date());
		txn.setTotal(100);
		
		Customer cust = new Customer();
		cust.setAddress("Bangalore, India");
		cust.setEmail("[email protected]");
		cust.setName("Pankaj Kumar");
		
		txn.setCustomer(cust);
		
		cust.setTxn(txn);
		return txn;
	}

}

עכשיו כאשר אנו מריצים את המיפוי החד לאחד לעיל בתוכנית הבדיקה של Hibernate, אנו מקבלים את הפלט הבא.

Hibernate Configuration loaded
Hibernate serviceRegistry created
Session created
Hibernate: insert into TRANSACTION (txn_date, txn_total) values (?, ?)
Hibernate: insert into CUSTOMER (cust_name, cust_email, cust_address, txn_id) values (?, ?, ?, ?)
Transaction ID=19
Hibernate: select txn0_.txn_id as txn_id1_1_0_, txn0_.txn_date as txn_date2_1_0_, txn0_.txn_total as txn_tota3_1_0_, 
customer1_.txn_id as txn_id1_0_1_, customer1_.cust_name as cust_nam2_0_1_, customer1_.cust_email as cust_ema3_0_1_, 
customer1_.cust_address as cust_add4_0_1_ from TRANSACTION txn0_ left outer join CUSTOMER customer1_ on 
txn0_.txn_id=customer1_.txn_id where txn0_.txn_id=?
Transaction Details=
19, 100.0, Pankaj Kumar, [email protected], Bangalore, India
Closing SessionFactory

כפי שאתה יכול לראות, הכל עובד בסדר ואנו מסוגלים לקבל נתונים משני הטבלאות באמצעות מזהה עסקאות. בדוק את ה- SQL שבו Hibernate משתמש פנימית כדי לקבל את הנתונים, הוא משתמש בחיבורים כדי לקבל את הנתונים משני הטבלאות.

Hibernate One to One Mapping Annotation

בקטע שלמעלה, ראינו כיצד להשתמש בתצורה מבוססת XML עבור הטבעת חיבור אחת לחיבור, עכשיו נראה איך ניתן להשתמש ב-JPA ובהערות Hibernate כדי להשיג את אותו הדבר.

Hibernate Configuration File

hibernate-annotation.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">pankaj123</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
        <property name="hibernate.connection.username">pankaj</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        
        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.show_sql">true</property>
        
        <mapping class="com.journaldev.hibernate.model.Txn1"/>
        <mapping class="com.journaldev.hibernate.model.Customer1"/>
    </session-factory>
</hibernate-configuration>

התצורה של Hibernate היא פשוטה, כפי שאתה יכול לראות שיש לי שני מודלים שנעשה בהם שימוש עם הערות – Txn1 ו- Customer1.

Hibernate One to One Mapping Annotation Example Model Classes

עבור התצורה של העתקת העצמים חד לחד בהיברנייט, דגש רב ניתן למחלקות המודל. בואו נראה כיצד מראים המחלקות שלנו.

package com.journaldev.hibernate.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;

@Entity
@Table(name="TRANSACTION")
public class Txn1 {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="txn_id")
	private long id;
	
	@Column(name="txn_date")
	private Date date;
	
	@Column(name="txn_total")
	private double total;
	
	@OneToOne(mappedBy="txn")
	@Cascade(value=org.hibernate.annotations.CascadeType.SAVE_UPDATE)
	private Customer1 customer;
	
	@Override
	public String toString(){
		return id+", "+total+", "+customer.getName()+", "+customer.getEmail()+", "+customer.getAddress();
	}

        // פעולות קבלה-הגדרה, שהתעלמנו מהן למען הבהירות 
}

שימו לב שרוב האנוטציות הן מתוך API של התקנת המידע של ג'אווה מפרסיסטנס מאחר והיברנייט מספק אותו. אך עבור התפשטות, נצטרך להשתמש באנוטציה של היברנייט org.hibernate.annotations.Cascade ובסוג הנתמך org.hibernate.annotations.CascadeType.

package com.journaldev.hibernate.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity
@Table(name="CUSTOMER")
public class Customer1 {

	@Id
	@Column(name="txn_id", unique=true, nullable=false)
	@GeneratedValue(generator="gen")
	@GenericGenerator(name="gen", strategy="foreign", parameters={@Parameter(name="property", value="txn")})
	private long id;
	
	@Column(name="cust_name")
	private String name;
	
	@Column(name="cust_email")
	private String email;
	
	@Column(name="cust_address")
	private String address;
	
	@OneToOne
	@PrimaryKeyJoinColumn
	private Txn1 txn;

        // פעולות קבלה-הגדרה
}

שימו לב שנצטרך להשתמש ב-@GenericGenerator כדי שהמזהה יופעל מהעסקה ולא ייווצר באופן אוטומטי.

מחלקת יעילות של ספריית SessionFactory של היברנייט

יצירת ה-SessionFactory אינה תלויה בדרך בה אנו מספקים את מיפוי ההיברנייט. מחלקת היעילות שלנו ליצירת SessionFactory נראית כך.

package com.journaldev.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateAnnotationUtil {

	private static SessionFactory sessionFactory;
	
	private static SessionFactory buildSessionFactory() {
        try {
            // יצירת ה-SessionFactory מתוך hibernate-annotation.cfg.xml
        	Configuration configuration = new Configuration();
        	configuration.configure("hibernate-annotation.cfg.xml");
        	System.out.println("Hibernate Annotation Configuration loaded");
        	
        	ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        	System.out.println("Hibernate Annotation serviceRegistry created");
        	
        	SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        	
            return sessionFactory;
        }
        catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
        }
    }
	
	public static SessionFactory getSessionFactory() {
		if(sessionFactory == null) sessionFactory = buildSessionFactory();
        return sessionFactory;
    }
}

דוגמה לתוכנית מבחן להתאמת חד לחד בהיברנייט עם אנוטציות

כאן תוכנית מבחן פשוטה עבור התאמת חד לחד בהיברנייט עם אנוטציות שלנו.

package com.journaldev.hibernate.main;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.journaldev.hibernate.model.Customer1;
import com.journaldev.hibernate.model.Txn1;
import com.journaldev.hibernate.util.HibernateAnnotationUtil;

public class HibernateOneToOneAnnotationMain {

	public static void main(String[] args) {
		
		Txn1 txn = buildDemoTransaction();
		
		SessionFactory sessionFactory = null;
		Session session = null;
		Transaction tx = null;
		try{
		//קבל ישיבה
		sessionFactory = HibernateAnnotationUtil.getSessionFactory();
		session = sessionFactory.getCurrentSession();
		System.out.println("Session created using annotations configuration");
		//התחל עסקה
		tx = session.beginTransaction();
		//שמור את אובייקט המודל
		session.save(txn);
		//בצע עסקה
		tx.commit();
		System.out.println("Annotation Example. Transaction ID="+txn.getId());
		
		//קבל נתוני עסקה שמורים
		printTransactionData(txn.getId(), sessionFactory);
		}catch(Exception e){
			System.out.println("Exception occured. "+e.getMessage());
			e.printStackTrace();
		}finally{
			if(sessionFactory != null && !sessionFactory.isClosed()){
				System.out.println("Closing SessionFactory");
				sessionFactory.close();
			}
		}
	}

	private static void printTransactionData(long id, SessionFactory sessionFactory) {
		Session session = null;
		Transaction tx = null;
		try{
			//קבל ישיבה
			sessionFactory = HibernateAnnotationUtil.getSessionFactory();
			session = sessionFactory.getCurrentSession();
			//התחל עסקה
			tx = session.beginTransaction();
			//שמור את אובייקט המודל
			Txn1 txn = (Txn1) session.get(Txn1.class, id);
			//בצע עסקה
			tx.commit();
			System.out.println("Annotation Example. Transaction Details=\n"+txn);
			
			}catch(Exception e){
				System.out.println("Exception occured. "+e.getMessage());
				e.printStackTrace();
			}
	}

	private static Txn1 buildDemoTransaction() {
		Txn1 txn = new Txn1();
		txn.setDate(new Date());
		txn.setTotal(100);
		
		Customer1 cust = new Customer1();
		cust.setAddress("San Jose, USA");
		cust.setEmail("[email protected]");
		cust.setName("Pankaj Kr");
		
		txn.setCustomer(cust);
		
		cust.setTxn(txn);
		return txn;
	}

}

כאן הוא קטע מתוצאת הרצת התוכנית כאשר אנו בוצעים את הפעולות שלמעלה.

Hibernate Annotation Configuration loaded
Hibernate Annotation serviceRegistry created
Session created using annotations configuration
Hibernate: insert into TRANSACTION (txn_date, txn_total) values (?, ?)
Hibernate: insert into CUSTOMER (cust_address, cust_email, cust_name, txn_id) values (?, ?, ?, ?)
Annotation Example. Transaction ID=20
Hibernate: select txn1x0_.txn_id as txn_id1_1_0_, txn1x0_.txn_date as txn_date2_1_0_, txn1x0_.txn_total as txn_tota3_1_0_, 
customer1x1_.txn_id as txn_id1_0_1_, customer1x1_.cust_address as cust_add2_0_1_, customer1x1_.cust_email as cust_ema3_0_1_, 
customer1x1_.cust_name as cust_nam4_0_1_ from TRANSACTION txn1x0_ left outer join CUSTOMER customer1x1_ on 
txn1x0_.txn_id=customer1x1_.txn_id where txn1x0_.txn_id=?
Annotation Example. Transaction Details=
20, 100.0, Pankaj Kr, [email protected], San Jose, USA
Closing SessionFactory

שים לב שהתוצאה דומה לתצורה XML של Hibernate ביחס אחד לאחד. זהו כל הדברים לדוגמא של מיפוי אחד לאחד ב-Hibernate, ניתן להוריד את הפרויקט הסופי מהקישור למטה ולשחק עם זה כדי ללמוד נוסף.

הורד את פרויקט מיפוי Hibernate OneToOne

Source:
https://www.digitalocean.com/community/tutorials/hibernate-one-to-one-mapping-example-annotation