1. खास जानकारी
Hibernate, Java प्रोजेक्ट के लिए ओआरएम का डिफ़ॉल्ट स्टैंडर्ड बन गया है. यह सभी मुख्य रिलेशनल डेटाबेस के साथ काम करता है. साथ ही, यह Spring Data JPA जैसे ज़्यादा बेहतर ORM टूल को भी चालू करता है. इसके अलावा, Hibernate के साथ काम करने वाले कई फ़्रेमवर्क हैं. जैसे, Spring Boot, Microprofile, और Quarkus.
Cloud Spanner Dialect for Hibernate ORM की मदद से, Cloud Spanner के साथ Hibernate का इस्तेमाल किया जा सकता है. आपको Cloud Spanner के फ़ायदे मिलते हैं. जैसे, स्केलेबिलिटी और रिलेशनल सिमैंटिक्स. साथ ही, Hibernate की इडियोमैटिक परसिस्टेंस की सुविधा भी मिलती है. इससे मौजूदा ऐप्लिकेशन को क्लाउड पर माइग्रेट करने या Hibernate पर आधारित टेक्नोलॉजी का इस्तेमाल करके नए ऐप्लिकेशन लिखने में मदद मिलती है. इससे डेवलपर की प्रॉडक्टिविटी बढ़ती है.
आपको क्या सीखने को मिलेगा
- Cloud Spanner से कनेक्ट होने वाला सामान्य Hibernate ऐप्लिकेशन लिखने का तरीका
- Cloud Spanner डेटाबेस बनाने का तरीका
- Hibernate ORM के लिए Cloud Spanner Dialect का इस्तेमाल करने का तरीका
- Hibernate की मदद से, क्रिएट-रीड-अपडेट-डिलीट (सीआरयूडी) ऑपरेशन लागू करने का तरीका
आपको इन चीज़ों की ज़रूरत होगी
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 के बारे में जानकारी दी गई होगी. अगर ऐसा होता है, तो जारी रखें पर क्लिक करें. इसके बाद, आपको यह स्क्रीन कभी नहीं दिखेगी. एक बार दिखने वाली स्क्रीन ऐसी दिखती है:
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 लॉन्च होने के बाद, gcloud का इस्तेमाल करके अपने GCP प्रोजेक्ट के साथ इंटरैक्ट किया जा सकता है.
सबसे पहले, 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 कोर की ज़रूरत होगी. इसलिए, pom.xml फ़ाइल में मौजूद <dependencies> ब्लॉक में ये डिपेंडेंसी जोड़ें.
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 इंस्टेंस से कैसे कनेक्ट करना है और किस डायलेक्ट का इस्तेमाल करना है. इसलिए, हम इसे 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 संबंध होगा. हम Singer को उनके Album की सूचियों के साथ @OneToMany एनोटेशन के साथ भी मैप कर सकते थे. हालांकि, इस उदाहरण के लिए, हमें डेटाबेस से किसी गायक को फ़ेच करने के लिए, हर बार सभी एल्बम लोड नहीं करने हैं.
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 क्वेरी लैंग्वेज (HQL) का इस्तेमाल करके कुछ क्वेरी चलाएंगे.
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", "Shaw", makeDate("1998-05-02")));
session.getTransaction().commit();
}
private static void readData(Session session) {
List<Singer> singers = session.createQuery("from Singer where birthDate >= '1990-01-01' order by lastName")
.list();
List<Album> 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. बधाई हो
बधाई हो, आपने Cloud Spanner में डेटा सेव करने के लिए, Hibernate का इस्तेमाल करके Java ऐप्लिकेशन बना लिया है.
- आपने Cloud Spanner इंस्टेंस और डेटाबेस बनाया हो
- आपने ऐप्लिकेशन को Hibernate का इस्तेमाल करने के लिए कॉन्फ़िगर किया हो
- आपने दो इकाइयां बनाई हैं: कलाकार और एल्बम
- आपने अपने ऐप्लिकेशन के लिए डेटाबेस स्कीमा अपने-आप जनरेट किया हो
- आपने Cloud Spanner में इकाइयां सेव कर ली हैं और उनसे जुड़ी क्वेरी कर ली हैं
अब आपको Cloud Spanner के साथ Hibernate ऐप्लिकेशन लिखने के लिए ज़रूरी मुख्य चरणों के बारे में पता चल गया है.