1. खास जानकारी
Hibernate, Java प्रोजेक्ट के लिए, डिफ़ॉल्ट ORM सलूशन बन गया है. यह सभी मुख्य रिलेशनल डेटाबेस के साथ काम करता है. साथ ही, Spring Data JPA जैसे ज़्यादा पावरफ़ुल ORM टूल के साथ भी काम करता है. इसके अलावा, Hibernate के साथ काम करने वाले कई फ़्रेमवर्क हैं. जैसे, Spring Boot, Microprofile, और Quarkus.
Hibernate ORM के लिए Cloud Spanner Dialect की मदद से, Hibernate को Cloud Spanner के साथ इस्तेमाल किया जा सकता है. आपको Cloud Spanner के फ़ायदे मिलते हैं. जैसे, स्केल करने की सुविधा और रिलेशनल सिमैंटिक्स. साथ ही, Hibernate की मदद से डेटा को सेव करने की सुविधा भी मिलती है. इससे, मौजूदा ऐप्लिकेशन को क्लाउड पर माइग्रेट करने या नए ऐप्लिकेशन लिखने में मदद मिल सकती है. ऐसा इसलिए, क्योंकि Hibernate पर आधारित टेक्नोलॉजी की मदद से, डेवलपर की प्रॉडक्टिविटी बढ़ जाती है.
आपको क्या सीखने को मिलेगा
- Cloud Spanner से कनेक्ट होने वाला, Hibernate का आसान ऐप्लिकेशन लिखने का तरीका
- Cloud Spanner डेटाबेस बनाने का तरीका
- Hibernate ORM के लिए Cloud Spanner Dialect का इस्तेमाल करने का तरीका
- Hibernate की मदद से, क्रिएट-रीड-अपडेट-डिलीट (CRUD) ऑपरेशन लागू करने का तरीका
आपको किन चीज़ों की ज़रूरत होगी
2. सेटअप और ज़रूरी शर्तें
अपनी रफ़्तार से सेटअप करने का तरीका
- Cloud Console में साइन इन करें और नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. (अगर आपके पास Gmail या G Suite खाता नहीं है, तो आपको एक खाता बनाना होगा.)
प्रोजेक्ट आईडी याद रखें. यह सभी Google Cloud प्रोजेक्ट के लिए एक यूनीक नाम होता है. ऊपर दिया गया नाम पहले ही लिया जा चुका है. इसलिए, यह आपके लिए काम नहीं करेगा. इसके लिए हमें अफ़सोस है! इस कोडलैब में इसे PROJECT_ID के तौर पर रेफ़र किया जाएगा.
- इसके बाद, Google Cloud के संसाधनों का इस्तेमाल करने के लिए, आपको Cloud Console में बिलिंग की सुविधा चालू करनी होगी.
इस कोडलैब को पूरा करने में ज़्यादा खर्च नहीं आएगा. "साफ़-सफ़ाई करना" सेक्शन में दिए गए निर्देशों का पालन करना न भूलें. इसमें बताया गया है कि संसाधनों को कैसे शट डाउन करें, ताकि इस ट्यूटोरियल के बाद आपको बिल न मिले. Google Cloud के नए उपयोगकर्ताओं के लिए, 300 डॉलर का मुफ़्त ट्रायल प्रोग्राम उपलब्ध है.
Cloud Shell चालू करें
- Cloud Console में, Cloud Shell चालू करें
पर क्लिक करें.
अगर आपने पहले कभी Cloud Shell शुरू नहीं किया है, तो आपको एक इंटरमीडिएट स्क्रीन (फ़ोल्ड के नीचे) दिखेगी. इसमें बताया जाएगा कि यह क्या है. ऐसा होने पर, जारी रखें पर क्लिक करें. इसके बाद, आपको यह स्क्रीन कभी नहीं दिखेगी. यहां वह स्क्रीन दिखती है जो एक बार दिखती है:
Cloud Shell को प्रोविज़न करने और उससे कनेक्ट होने में बस कुछ सेकंड लगेंगे.
इस वर्चुअल मशीन में, डेवलपमेंट के लिए ज़रूरी सभी टूल लोड होते हैं. इसमें 5 जीबी की होम डायरेक्ट्री होती है. साथ ही, यह Google Cloud में चलता है. इससे नेटवर्क की परफ़ॉर्मेंस और पुष्टि करने की प्रोसेस बेहतर होती है. इस कोडलैब में ज़्यादातर काम, सिर्फ़ ब्राउज़र या Chromebook की मदद से किया जा सकता है.
Cloud Shell से कनेक्ट होने के बाद, आपको दिखेगा कि आपकी पुष्टि हो चुकी है और प्रोजेक्ट पहले से ही आपके प्रोजेक्ट आईडी पर सेट है.
- पुष्टि करने के लिए, Cloud Shell में यह कमांड चलाएं:
gcloud auth list
कमांड का आउटपुट
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
gcloud config list project
कमांड का आउटपुट
[core] project = <PROJECT_ID>
अगर ऐसा नहीं है, तो इस कमांड से इसे सेट किया जा सकता है:
gcloud config set project <PROJECT_ID>
कमांड का आउटपुट
Updated property [core/project].
3. डेटाबेस बनाना
Cloud Shell लॉन्च होने के बाद, अपने GCP प्रोजेक्ट के साथ इंटरैक्ट करने के लिए, gcloud का इस्तेमाल किया जा सकता है.
सबसे पहले, Cloud Spanner API चालू करें.
gcloud services enable spanner.googleapis.com
अब, codelab-instance नाम का Cloud Spanner इंस्टेंस बनाते हैं.
gcloud spanner instances create codelab-instance \ --config=regional-us-central1 \ --description="Codelab Instance" --nodes=1
अब हमें इस इंस्टेंस में एक डेटाबेस जोड़ना होगा. हम इसे codelab-db नाम देंगे.
gcloud spanner databases create codelab-db --instance=codelab-instance
4. खाली ऐप्लिकेशन बनाना
हम Java का आसान कंसोल ऐप्लिकेशन बनाने के लिए, Maven Quickstart Archetype का इस्तेमाल करेंगे.
mvn archetype:generate \ -DgroupId=codelab \ -DartifactId=spanner-hibernate-codelab \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DarchetypeVersion=1.4 \ -DinteractiveMode=false
ऐप्लिकेशन की डायरेक्ट्री पर जाएं.
cd spanner-hibernate-codelab
Maven का इस्तेमाल करके, ऐप्लिकेशन को कंपाइल करें और चलाएं.
mvn compile exec:java -Dexec.mainClass=codelab.App
आपको कंसोल में Hello World! लिखा हुआ दिखेगा.
5. डिपेंडेंसी जोड़ें
Cloud Shell Editor खोलकर और spanner-hibernate-codelab डायरेक्ट्री में जाकर, सोर्स कोड एक्सप्लोर करते हैं.

अब तक, हमारे पास सिर्फ़ Java का एक बुनियादी कंसोल ऐप्लिकेशन है, जो "Hello World!" प्रिंट करता है. हालांकि, हम ऐसा Java ऐप्लिकेशन लिखना चाहते हैं जो Cloud Spanner से बात करने के लिए Hibernate का इस्तेमाल करता हो. इसके लिए, हमें Hibernate के लिए Cloud Spanner Dialect, Cloud Spanner JDBC ड्राइवर, और Hibernate कोर की ज़रूरत होगी. इसलिए, <dependencies> फ़ाइल में मौजूद pom.xml ब्लॉक में ये डिपेंडेंसी जोड़ते हैं.
pom.xml
<!-- Spanner Dialect -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner-hibernate-dialect</artifactId>
<version>1.5.0</version>
</dependency>
<!-- JDBC Driver -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner-jdbc</artifactId>
<version>2.0.0</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.29.Final</version>
</dependency>
6. Hibernate ORM को कॉन्फ़िगर करना
इसके बाद, हम Hibernate की कॉन्फ़िगरेशन फ़ाइलें hibernate.cfg.xml और hibernate.properties बनाएंगे. खाली फ़ाइलें बनाने के लिए, यह कमांड चलाएं. इसके बाद, Cloud Shell Editor का इस्तेमाल करके, इनमें बदलाव करें.
mkdir src/main/resources \ && touch src/main/resources/hibernate.cfg.xml \ && touch src/main/resources/hibernate.properties
अब, hibernate.cfg.xml में जानकारी भरकर, Hibernate को एनोटेट की गई उन एंटिटी क्लास के बारे में बताते हैं जिन्हें हम डेटाबेस में मैप करेंगे. (हम एंटिटी क्लास बाद में बनाएंगे.)
src/main/resources/hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<!-- Annotated entity classes -->
<mapping class="codelab.Album"/>
<mapping class="codelab.Singer"/>
</session-factory>
</hibernate-configuration>
Hibernate को यह भी पता होना चाहिए कि Cloud Spanner इंस्टेंस से कैसे कनेक्ट किया जाए और किस Dialect का इस्तेमाल किया जाए. इसलिए, हम इसे SQL सिंटैक्स के लिए SpannerDialect, Spanner JDBC ड्राइवर, और डेटाबेस कोऑर्डिनेट के साथ JDBC कनेक्शन स्ट्रिंग का इस्तेमाल करने के लिए कहेंगे. यह जानकारी hibernate.properties फ़ाइल में जाती है.
src/main/resources/hibernate.properties
hibernate.dialect=com.google.cloud.spanner.hibernate.SpannerDialect
hibernate.connection.driver_class=com.google.cloud.spanner.jdbc.JdbcDriver
hibernate.connection.url=jdbc:cloudspanner:/projects/{PROJECT_ID}/instances/codelab-instance/databases/codelab-db
# auto-create or update DB schema
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
{PROJECT_ID} को अपने प्रोजेक्ट आईडी से बदलना न भूलें. इसे पाने के लिए, यह कमांड चलाएं:
gcloud config get-value project
हमारे पास कोई मौजूदा डेटाबेस स्कीमा नहीं है. इसलिए, हमने hibernate.hbm2ddl.auto=update प्रॉपर्टी जोड़ी है, ताकि पहली बार ऐप्लिकेशन चलाने पर, Hibernate Cloud Spanner में दो टेबल बना सके.
आम तौर पर, आपको यह भी पक्का करना होगा कि पुष्टि करने के क्रेडेंशियल सेट अप किए गए हों. इसके लिए, GOOGLE_APPLICATION_CREDENTIALS एनवायरमेंट वैरिएबल में सेवा खाते की JSON फ़ाइल या gcloud auth application-default login कमांड का इस्तेमाल करके कॉन्फ़िगर किए गए ऐप्लिकेशन के डिफ़ॉल्ट क्रेडेंशियल का इस्तेमाल किया जाता है. हालांकि, हम Cloud Shell में काम कर रहे हैं. इसलिए, डिफ़ॉल्ट प्रोजेक्ट क्रेडेंशियल पहले से ही सेट अप हैं.
7. एनोटेट की गई एंटिटी क्लास बनाना
अब हम कुछ कोड लिखने के लिए तैयार हैं.
हम दो प्लेन ओल्ड Java ऑब्जेक्ट (पीओजेओ) तय करेंगे. इन्हें Cloud Spanner में मौजूद टेबल—Singer और Album में मैप किया जाएगा. Album का Singer के साथ @ManyToOne रिलेशनशिप होगा. हम @OneToMany एनोटेशन की मदद से, Singer को उनके Album की सूचियों में भी मैप कर सकते थे. हालांकि, इस उदाहरण के लिए, हम डेटाबेस से किसी सिंगर को फ़ेच करने के लिए, हर बार सभी एल्बम लोड नहीं करना चाहते.
Singer और Album एंटिटी क्लास जोड़ें.
क्लास फ़ाइलें बनाएं.
touch src/main/java/codelab/Singer.java \ && touch src/main/java/codelab/Album.java
फ़ाइलों का कॉन्टेंट चिपकाएं.
src/main/java/codelab/Singer.java
package codelab;
import java.util.Date;
import java.util.UUID;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.Type;
@Entity
public class Singer {
@Id
@GeneratedValue
@Type(type = "uuid-char")
private UUID singerId;
private String firstName;
private String lastName;
@Temporal(TemporalType.DATE)
private Date birthDate;
public Singer() {
}
public Singer(String firstName, String lastName, Date birthDate) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDate = birthDate;
}
public UUID getSingerId() {
return singerId;
}
public void setSingerId(UUID singerId) {
this.singerId = singerId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Singer)) {
return false;
}
Singer singer = (Singer) o;
if (!firstName.equals(singer.firstName)) {
return false;
}
if (!lastName.equals(singer.lastName)) {
return false;
}
return birthDate.equals(singer.birthDate);
}
@Override
public int hashCode() {
int result = firstName.hashCode();
result = 31 * result + lastName.hashCode();
result = 31 * result + birthDate.hashCode();
return result;
}
}
src/main/java/codelab/Album.java
package codelab;
import java.util.UUID;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.Type;
@Entity
public class Album {
@Id
@GeneratedValue
@Type(type = "uuid-char")
UUID albumId;
@ManyToOne
Singer singer;
String albumTitle;
public Album() {
}
public Album(Singer singer, String albumTitle) {
this.singer = singer;
this.albumTitle = albumTitle;
}
public UUID getAlbumId() {
return albumId;
}
public void setAlbumId(UUID albumId) {
this.albumId = albumId;
}
public Singer getSinger() {
return singer;
}
public void setSinger(Singer singer) {
this.singer = singer;
}
public String getAlbumTitle() {
return albumTitle;
}
public void setAlbumTitle(String albumTitle) {
this.albumTitle = albumTitle;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Album)) {
return false;
}
Album album = (Album) o;
if (!singer.equals(album.singer)) {
return false;
}
return albumTitle.equals(album.albumTitle);
}
@Override
public int hashCode() {
int result = singer.hashCode();
result = 31 * result + albumTitle.hashCode();
return result;
}
}
ध्यान दें कि इस उदाहरण के लिए, हम प्राइमरी कुंजी के लिए अपने-आप जनरेट होने वाले यूयूआईडी का इस्तेमाल कर रहे हैं. Cloud Spanner में यह आईडी टाइप बेहतर है, क्योंकि इससे हॉटस्पॉट से बचा जा सकता है. ऐसा इसलिए, क्योंकि सिस्टम, कुंजी की रेंज के हिसाब से डेटा को सर्वर के बीच बांटता है. मोनोटोनिकली बढ़ने वाली इंटिजर कुंजी भी काम करेगी, लेकिन इसकी परफ़ॉर्मेंस कम हो सकती है.
8. एंटिटी सेव करना और क्वेरी करना
सब कुछ कॉन्फ़िगर करने और एंटिटी ऑब्जेक्ट तय करने के बाद, हम डेटाबेस में डेटा लिखना और क्वेरी करना शुरू कर सकते हैं. हम Hibernate Session खोलेंगे. इसके बाद, इसका इस्तेमाल करके, सबसे पहले clearData() तरीके में सभी टेबल की पंक्तियों को मिटाएंगे. इसके बाद, writeData() तरीके में कुछ एंटिटी सेव करेंगे. इसके बाद, readData() तरीके में Hibernate क्वेरी लैंग्वेज (एचक्यूएल) का इस्तेमाल करके कुछ क्वेरी चलाएंगे.
App.java के कॉन्टेंट को इससे बदलें:
src/main/java/codelab/App.java
package codelab;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class App {
public final static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
public static void main(String[] args) {
// create a Hibernate sessionFactory and session
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata()
.buildSessionFactory();
Session session = sessionFactory.openSession();
clearData(session);
writeData(session);
readData(session);
// close Hibernate session and sessionFactory
session.close();
sessionFactory.close();
}
private static void clearData(Session session) {
session.beginTransaction();
session.createQuery("delete from Album where 1=1").executeUpdate();
session.createQuery("delete from Singer where 1=1").executeUpdate();
session.getTransaction().commit();
}
private static void writeData(Session session) {
session.beginTransaction();
Singer singerMelissa = new Singer("Melissa", "Garcia", makeDate("1981-03-19"));
Album albumGoGoGo = new Album(singerMelissa, "Go, Go, Go");
session.save(singerMelissa);
session.save(albumGoGoGo);
session.save(new Singer("Russell", "Morales", makeDate("1978-12-02")));
session.save(new Singer("Jacqueline", "Long", makeDate("1990-07-29")));
session.save(new Singer("Dylan"<;, &qu>ot;Shaw", makeDate("1998-05-02")));
sess>ion.getTransaction().commit();
}
private static void re<adDat>a(Session session) {
ListSinger singers = session.createQuery("from Singer where birthDate = '1990-01-01' order by lastName")
.list();
ListAlbum albums = session.createQuery("from Album").list();
System.out.println("Singers who were born in 1990 or later:");
for (Singer singer : singers) {
System.out.println(singer.getFirstName() + " " + singer.getLastName() + " born on "
+ DATE_FORMAT.format(singer.getBirthDate()));
}
System.out.println("Albums: ");
for (Album album : albums) {
System.out
.println("\"" + album.getAlbumTitle() + "\" by " + album.getSinger().getFirstName() + " "
+ album.getSinger().getLastName());
}
}
private static Date makeDate(String dateString) {
try {
return DATE_FORMAT.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
}
अब, कोड को कंपाइल करें और चलाएं. हम -Dexec.cleanupDaemonThreads=false विकल्प जोड़ेंगे, ताकि डेमॉन थ्रेड की साफ़-सफ़ाई के बारे में चेतावनियां न दिखें. Maven, डेमॉन थ्रेड की साफ़-सफ़ाई करने की कोशिश करेगा.
mvn compile exec:java -Dexec.mainClass=codelab.App -Dexec.cleanupDaemonThreads=false
आउटपुट में आपको कुछ ऐसा दिखेगा:
Singers who were born in 1990 or later: Jacqueline Long born on 1990-07-29 Dylan Shaw born on 1998-05-02 Albums: "Go, Go, Go" by Melissa Garcia
इस समय, अगर आप Cloud Spanner कंसोल पर जाते हैं और डेटाबेस में Singer और Album टेबल का डेटा देखते हैं, तो आपको कुछ ऐसा दिखेगा:


9. स्टोरेज में जगह बनाएं
शुरुआत में बनाए गए Cloud Spanner इंस्टेंस को मिटाते हैं, ताकि यह पक्का किया जा सके कि यह बिना वजह संसाधनों का इस्तेमाल न करे.
gcloud spanner instances delete codelab-instance
10. बधाई हो
बधाई हो, आपने Java का एक ऐसा ऐप्लिकेशन बना लिया है जो Cloud Spanner में डेटा सेव करने के लिए Hibernate का इस्तेमाल करता है.
- आपने Cloud Spanner इंस्टेंस और डेटाबेस बनाया
- आपने Hibernate का इस्तेमाल करने के लिए, ऐप्लिकेशन को कॉन्फ़िगर किया
- आपने दो एंटिटी बनाईं: Artist और Album
- आपने अपने ऐप्लिकेशन के लिए, डेटाबेस स्कीमा अपने-आप जनरेट किया
- आपने Cloud Spanner में एंटिटी सेव कीं और उनके लिए क्वेरी कीं
अब आपको Cloud Spanner के साथ Hibernate ऐप्लिकेशन लिखने के लिए ज़रूरी मुख्य चरणों के बारे में पता चल गया है.