{"id":31540,"date":"2025-10-11T02:41:02","date_gmt":"2025-10-10T23:41:02","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=31540"},"modified":"2025-10-11T02:41:02","modified_gmt":"2025-10-10T23:41:02","slug":"hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/","title":{"rendered":"Hibernate&#8217;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri"},"content":{"rendered":"<p><body><\/p>\n<h2>Hibernate&#8217;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri<\/h2>\n<h2>Giri\u015f: \u00c7oka-\u00c7ok \u0130li\u015fkiler ve Veritaban\u0131 Tasar\u0131m\u0131<\/h2>\n<p>Veritaban\u0131 tasar\u0131m\u0131nda ili\u015fkiler, farkl\u0131 veri k\u00fcmeleri aras\u0131ndaki ba\u011flant\u0131lar\u0131 tan\u0131mlaman\u0131n temelini olu\u015fturur. Bu ili\u015fkiler genellikle bire-bir (One-to-One), bire-\u00e7ok (One-to-Many) veya \u00e7oka-\u00e7ok (Many-to-Many) \u015feklinde s\u0131n\u0131fland\u0131r\u0131l\u0131r. \u00c7oka-\u00e7ok ili\u015fkiler, ger\u00e7ek d\u00fcnya senaryolar\u0131nda olduk\u00e7a yayg\u0131n olup, iki varl\u0131k setindeki her bir eleman\u0131n di\u011fer setin birden fazla eleman\u0131yla ili\u015fkili olabilece\u011fi durumlar\u0131 ifade eder. \u00d6rne\u011fin, bir yazar birden fazla kitap yazabilir ve bir kitap birden fazla yazar taraf\u0131ndan yaz\u0131lm\u0131\u015f olabilir. Benzer \u015fekilde, bir \u00f6\u011frenci birden fazla derse kaydolabilir ve bir derse birden fazla \u00f6\u011frenci kaydolabilir. Bu t\u00fcr ili\u015fkilerin do\u011fru bir \u015fekilde modellenmesi ve y\u00f6netilmesi, veritaban\u0131 uygulamalar\u0131n\u0131n performans\u0131 ve veri b\u00fct\u00fcnl\u00fc\u011f\u00fc a\u00e7\u0131s\u0131ndan kritik \u00f6neme sahiptir.<\/p>\n<h3>\u00c7oka-\u00c7ok \u0130li\u015fki Nedir?<\/h3>\n<p>\u00c7oka-\u00e7ok ili\u015fki, bir A varl\u0131k k\u00fcmesindeki her bir eleman\u0131n B varl\u0131k k\u00fcmesindeki s\u0131f\u0131r, bir veya daha fazla elemanla ili\u015fkili olabilece\u011fi ve ayn\u0131 \u015fekilde B varl\u0131k k\u00fcmesindeki her bir eleman\u0131n A varl\u0131k k\u00fcmesindeki s\u0131f\u0131r, bir veya daha fazla elemanla ili\u015fkili olabilece\u011fi durumu tan\u0131mlar. Bu ili\u015fki t\u00fcr\u00fc, karma\u015f\u0131k veri modellerini basitle\u015ftirmek ve veri tekrar\u0131n\u0131 \u00f6nlemek i\u00e7in kullan\u0131l\u0131r. \u0130li\u015fkisel veritabanlar\u0131nda do\u011frudan bir &#8220;\u00e7oka-\u00e7ok&#8221; ili\u015fki s\u00fctunu tan\u0131mlamak m\u00fcmk\u00fcn de\u011fildir. Bu nedenle, bu ili\u015fkileri temsil etmek i\u00e7in \u00f6zel bir yakla\u015f\u0131m benimsenir.<\/p>\n<h3>Veritabanlar\u0131nda \u00c7oka-\u00c7ok \u0130li\u015fkilerin Temsili: Ba\u011flant\u0131 Tablolar\u0131<\/h3>\n<p>\u0130li\u015fkisel veritabanlar\u0131nda \u00e7oka-\u00e7ok ili\u015fkiler, genellikle &#8220;ba\u011flant\u0131 tablosu&#8221; (join table, junction table veya associative table) ad\u0131 verilen \u00fc\u00e7\u00fcnc\u00fc bir tablo arac\u0131l\u0131\u011f\u0131yla temsil edilir. Bu ba\u011flant\u0131 tablosu, ili\u015fkiyi olu\u015fturan her iki ana tablonun birincil anahtarlar\u0131n\u0131 (primary key) yabanc\u0131 anahtar (foreign key) olarak i\u00e7erir. Bu iki yabanc\u0131 anahtar\u0131n birle\u015fimi, ba\u011flant\u0131 tablosunun birincil anahtar\u0131n\u0131 (bile\u015fik anahtar &#8211; composite key) olu\u015fturur ve b\u00f6ylece her iki varl\u0131k aras\u0131ndaki benzersiz bir ili\u015fkiyi tan\u0131mlar.<\/p>\n<p>\u00d6rne\u011fin, &#8220;Yazar&#8221; ve &#8220;Kitap&#8221; aras\u0131ndaki \u00e7oka-\u00e7ok ili\u015fkiyi d\u00fc\u015f\u00fcnelim. Bir <code>YAZARLAR<\/code> tablosu (id, ad, soyad) ve bir <code>K\u0130TAPLAR<\/code> tablosu (id, ba\u015fl\u0131k, yay\u0131n_y\u0131l\u0131) olabilir. Bu iki tablo aras\u0131ndaki ili\u015fkiyi kurmak i\u00e7in <code>YAZAR_K\u0130TAP<\/code> ad\u0131nda bir ba\u011flant\u0131 tablosu olu\u015fturulur. Bu tablo, <code>yazar_id<\/code> (YAZARLAR tablosundan gelen yabanc\u0131 anahtar) ve <code>kitap_id<\/code> (K\u0130TAPLAR tablosundan gelen yabanc\u0131 anahtar) s\u00fctunlar\u0131n\u0131 i\u00e7erir. Bu iki s\u00fctun birlikte <code>YAZAR_K\u0130TAP<\/code> tablosunun birincil anahtar\u0131n\u0131 olu\u015fturur. B\u00f6ylece, bir yazar\u0131n birden fazla kitapla, bir kitab\u0131n da birden fazla yazarla ili\u015fkisi bu ba\u011flant\u0131 tablosu \u00fczerinden kurulur.<\/p>\n<h2>Hibernate ve Nesne-\u0130li\u015fkisel Haritalama (ORM)<\/h2>\n<p>Modern Java uygulamalar\u0131nda veritaban\u0131 etkile\u015fimleri i\u00e7in s\u0131kl\u0131kla Nesne-\u0130li\u015fkisel Haritalama (ORM) ara\u00e7lar\u0131 kullan\u0131l\u0131r. Hibernate, Java d\u00fcnyas\u0131ndaki en pop\u00fcler ve g\u00fc\u00e7l\u00fc ORM framework&#8217;lerinden biridir. ORM, uygulama katman\u0131ndaki nesneler ile veritaban\u0131ndaki tablolar aras\u0131nda bir k\u00f6pr\u00fc g\u00f6revi g\u00f6rerek geli\u015ftiricilerin SQL sorgular\u0131 yazma ihtiyac\u0131n\u0131 azalt\u0131r ve veri eri\u015fimini daha nesne odakl\u0131 hale getirir.<\/p>\n<h3>Hibernate&#8217;in Rol\u00fc ve ORM Prensipleri<\/h3>\n<p>Hibernate, Java nesnelerini (POJO&#8217;lar &#8211; Plain Old Java Objects) veritaban\u0131 tablolar\u0131na haritalayarak, geli\u015ftiricilerin veritaban\u0131 i\u015flemlerini do\u011frudan SQL yazmak yerine Java nesneleri \u00fczerinde yapmas\u0131n\u0131 sa\u011flar. Bu sayede, geli\u015ftirme s\u00fcreci h\u0131zlan\u0131r, kod daha okunabilir ve bak\u0131m\u0131 daha kolay hale gelir. Hibernate, veritaban\u0131 ba\u011f\u0131ms\u0131zl\u0131\u011f\u0131 da sa\u011flar; yani, ayn\u0131 kod farkl\u0131 veritaban\u0131 sistemlerinde (MySQL, PostgreSQL, Oracle vb.) k\u00fc\u00e7\u00fck konfig\u00fcrasyon de\u011fi\u015fiklikleriyle \u00e7al\u0131\u015fabilir.<\/p>\n<h3>Varl\u0131klar, Haritalamalar ve Oturumlar<\/h3>\n<p>Hibernate&#8217;te, veritaban\u0131 tablolar\u0131na kar\u015f\u0131l\u0131k gelen Java s\u0131n\u0131flar\u0131na &#8220;varl\u0131klar&#8221; (entities) denir. Bu varl\u0131k s\u0131n\u0131flar\u0131, tablonun s\u00fctunlar\u0131na kar\u015f\u0131l\u0131k gelen alanlara (fields) sahiptir. Hibernate, bu varl\u0131klar\u0131 veritaban\u0131 tablolar\u0131na nas\u0131l haritalayaca\u011f\u0131n\u0131 tan\u0131mlamak i\u00e7in XML dosyalar\u0131 veya Java annotasyonlar\u0131 kullan\u0131r. G\u00fcn\u00fcm\u00fczde genellikle annotasyonlar tercih edilmektedir.<\/p>\n<p>Bir Hibernate uygulamas\u0131nda, veritaban\u0131 i\u015flemleri &#8220;oturum&#8221; (Session) nesneleri arac\u0131l\u0131\u011f\u0131yla ger\u00e7ekle\u015ftirilir. Bir <code>Session<\/code> nesnesi, veritaban\u0131 ile etkile\u015fim kurmak i\u00e7in birincil aray\u00fczd\u00fcr. Varl\u0131klar\u0131 kal\u0131c\u0131 hale getirmek (persist), almak (retrieve), g\u00fcncellemek (update) veya silmek (delete) gibi t\u00fcm CRUD (Create, Read, Update, Delete) operasyonlar\u0131 bir oturum ba\u011flam\u0131nda yap\u0131l\u0131r. \u0130\u015flemler genellikle bir &#8220;i\u015flem&#8221; (Transaction) i\u00e7inde grupland\u0131r\u0131l\u0131r ve atomik olarak y\u00fcr\u00fct\u00fcl\u00fcr.<\/p>\n<h2>Hibernate ile \u00c7oka-\u00c7ok \u0130li\u015fki Haritalama Temelleri<\/h2>\n<p>Hibernate, \u00e7oka-\u00e7ok ili\u015fkileri <code>@ManyToMany<\/code> annotasyonu ve <code>@JoinTable<\/code> annotasyonu ile kolayca haritalamam\u0131z\u0131 sa\u011flar. Bu annotasyonlar, ba\u011flant\u0131 tablosunun nas\u0131l olu\u015fturulaca\u011f\u0131n\u0131 ve varl\u0131klar aras\u0131ndaki ili\u015fkilerin nas\u0131l y\u00f6netilece\u011fini belirtir.<\/p>\n<h3>Varl\u0131k Tasar\u0131m\u0131 ve Annotasyonlar<\/h3>\n<p>\u00c7oka-\u00e7ok ili\u015fkiyi haritalamak i\u00e7in her iki varl\u0131k s\u0131n\u0131f\u0131nda da bir koleksiyon (genellikle <code>Set<\/code> veya <code>List<\/code>) tan\u0131mlan\u0131r ve bu koleksiyon <code>@ManyToMany<\/code> annotasyonu ile i\u015faretlenir.<\/p>\n<h4>@ManyToMany Annotasyonu<\/h4>\n<p><code>@ManyToMany<\/code> annotasyonu, bir varl\u0131\u011f\u0131n di\u011fer varl\u0131kla \u00e7oka-\u00e7ok ili\u015fkisi oldu\u011funu belirtir. Bu annotasyon, genellikle bir koleksiyon alan\u0131n\u0131n \u00fczerinde kullan\u0131l\u0131r.<\/p>\n<pre><code class=\"language-java\">public class Yazar {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n    private String ad;\n    private String soyad;\n\n    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)\n    private Set<Kitap> kitaplar = new HashSet<>();\n\n    \/\/ Getter ve Setter metotlar\u0131\n}\n\npublic class Kitap {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n    private String baslik;\n    private int yayinYili;\n\n    @ManyToMany(mappedBy = \"kitaplar\", cascade = CascadeType.ALL, fetch = FetchType.LAZY)\n    private Set<Yazar> yazarlar = new HashSet<>();\n\n    \/\/ Getter ve Setter metotlar\u0131\n}<\/code><\/pre>\n<p>Yukar\u0131daki \u00f6rnekte, <code>Yazar<\/code> s\u0131n\u0131f\u0131 <code>Kitap<\/code> nesnelerinin bir <code>Set<\/code>&#8216;ini, <code>Kitap<\/code> s\u0131n\u0131f\u0131 ise <code>Yazar<\/code> nesnelerinin bir <code>Set<\/code>&#8216;ini i\u00e7erir. Her iki koleksiyon da <code>@ManyToMany<\/code> ile i\u015faretlenmi\u015ftir.<\/p>\n<h4>@JoinTable Annotasyonu<\/h4>\n<p><code>@JoinTable<\/code> annotasyonu, \u00e7oka-\u00e7ok ili\u015fkisi i\u00e7in kullan\u0131lacak ba\u011flant\u0131 tablosunun ad\u0131n\u0131 ve s\u00fctunlar\u0131n\u0131 belirtmek i\u00e7in kullan\u0131l\u0131r. Bu annotasyon, ili\u015fkinin &#8220;owning side&#8221; (sahip taraf\u0131) olarak adland\u0131r\u0131lan taraf\u0131nda kullan\u0131l\u0131r.<\/p>\n<pre><code class=\"language-java\">public class Yazar {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n    private String ad;\n    private String soyad;\n\n    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)\n    @JoinTable(\n        name = \"yazar_kitap\", \/\/ Ba\u011flant\u0131 tablosunun ad\u0131\n        joinColumns = @JoinColumn(name = \"yazar_id\"), \/\/ Yazar tablosundan gelen s\u00fctun\n        inverseJoinColumns = @JoinColumn(name = \"kitap_id\") \/\/ Kitap tablosundan gelen s\u00fctun\n    )\n    private Set<Kitap> kitaplar = new HashSet<>();\n\n    \/\/ Getter ve Setter metotlar\u0131\n}<\/code><\/pre>\n<p><code>@JoinTable<\/code> i\u00e7indeki parametreler:<br \/>\n*   <code>name<\/code>: Ba\u011flant\u0131 tablosunun veritaban\u0131ndaki ad\u0131n\u0131 belirtir (\u00f6rn. <code>yazar_kitap<\/code>).<br \/>\n*   <code>joinColumns<\/code>: \u0130li\u015fkinin tan\u0131mland\u0131\u011f\u0131 varl\u0131\u011f\u0131n (bu \u00f6rnekte <code>Yazar<\/code>) birincil anahtar\u0131n\u0131 ba\u011flant\u0131 tablosunda temsil eden s\u00fctunu belirtir (<code>yazar_id<\/code>).<br \/>\n*   <code>inverseJoinColumns<\/code>: \u0130li\u015fkinin kar\u015f\u0131 taraf\u0131ndaki varl\u0131\u011f\u0131n (bu \u00f6rnekte <code>Kitap<\/code>) birincil anahtar\u0131n\u0131 ba\u011flant\u0131 tablosunda temsil eden s\u00fctunu belirtir (<code>kitap_id<\/code>).<\/p>\n<h4>Owning taraf\u0131 ve inverse taraf\u0131: mappedBy<\/h4>\n<p>\u00c7oka-\u00e7ok ili\u015fkilerde, Hibernate&#8217;in hangi taraf\u0131n ili\u015fkiyi y\u00f6netti\u011fini bilmesi gerekir. Bu, &#8220;owning side&#8221; (sahip taraf\u0131) ve &#8220;inverse side&#8221; (ters taraf) kavramlar\u0131yla ifade edilir.<br \/>\n*   <strong>Owning Side (Sahip Taraf\u0131)<\/strong>: Bu taraf, ili\u015fkinin veritaban\u0131nda nas\u0131l haritalanaca\u011f\u0131n\u0131 tan\u0131mlayan <code>@JoinTable<\/code> annotasyonunu i\u00e7erir. \u0130li\u015fkiyi y\u00f6neten taraft\u0131r ve de\u011fi\u015fiklikler bu taraf \u00fczerinden veritaban\u0131na yans\u0131t\u0131l\u0131r. Genellikle, <code>Yazar<\/code> varl\u0131\u011f\u0131ndaki <code>kitaplar<\/code> koleksiyonu owning taraf\u0131 olarak se\u00e7ilir.<br \/>\n*   <strong>Inverse Side (Ters Taraf)<\/strong>: Bu taraf, <code>mappedBy<\/code> \u00f6zelli\u011fini kullanarak owning taraf\u0131n\u0131n ad\u0131n\u0131 belirtir. Inverse taraf\u0131, ili\u015fkiyi kendisi y\u00f6netmez, sadece owning taraf\u0131n\u0131n y\u00f6netti\u011fi ili\u015fkiyi yans\u0131t\u0131r. <code>Kitap<\/code> varl\u0131\u011f\u0131ndaki <code>yazarlar<\/code> koleksiyonu inverse taraft\u0131r ve <code>mappedBy = \"kitaplar\"<\/code> ile <code>Yazar<\/code> varl\u0131\u011f\u0131ndaki <code>kitaplar<\/code> alan\u0131n\u0131 i\u015faret eder.<\/p>\n<p><code>mappedBy<\/code> kullan\u0131m\u0131, Hibernate&#8217;in ayn\u0131 ili\u015fki i\u00e7in iki ayr\u0131 ba\u011flant\u0131 tablosu olu\u015fturmas\u0131n\u0131 engeller ve veritaban\u0131 \u015femas\u0131n\u0131 do\u011fru bir \u015fekilde olu\u015fturmas\u0131n\u0131 sa\u011flar. \u0130li\u015fkisel veritaban\u0131nda tek bir ba\u011flant\u0131 tablosu oldu\u011fundan, Hibernate&#8217;in bu tablonun y\u00f6netimini tek bir tarafa b\u0131rakmas\u0131 gerekir.<\/p>\n<h4>Koleksiyon Tipleri: Set vs. List<\/h4>\n<p>\u00c7oka-\u00e7ok ili\u015fkilerde koleksiyon tipi olarak genellikle <code>java.util.Set<\/code> veya <code>java.util.List<\/code> kullan\u0131l\u0131r.<br \/>\n*   <strong><code>Set<\/code><\/strong>: \u00c7o\u011fu durumda tercih edilen se\u00e7enektir \u00e7\u00fcnk\u00fc Set, elemanlar\u0131n benzersizli\u011fini garanti eder. Bu, ayn\u0131 yazar\u0131n ayn\u0131 kitaba iki kez atanmas\u0131n\u0131 engeller. Ayr\u0131ca, Set&#8217;ler genellikle daha iyi performans sunar, \u00f6zellikle eleman ekleme ve \u00e7\u0131karma i\u015flemlerinde.<br \/>\n*   <strong><code>List<\/code><\/strong>: E\u011fer ili\u015fkili elemanlar\u0131n s\u0131ras\u0131n\u0131n korunmas\u0131 \u00f6nemliyse veya ayn\u0131 eleman\u0131n birden fazla kez ili\u015fkilendirilmesi gerekiyorsa (ki \u00e7oka-\u00e7ok ili\u015fkide bu nadirdir), <code>List<\/code> kullan\u0131labilir. Ancak, <code>List<\/code> kullan\u0131ld\u0131\u011f\u0131nda Hibernate, koleksiyonun s\u0131ras\u0131n\u0131 korumak i\u00e7in ek bir s\u0131ralama s\u00fctunu (index column) ekleyebilir.<\/p>\n<h3>\u00d6rnek Senaryo: Yazar ve Kitap \u0130li\u015fkisi<\/h3>\n<p>\u015eimdi Yazar ve Kitap aras\u0131ndaki \u00e7oka-\u00e7ok ili\u015fkiyi somut bir \u00f6rnekle inceleyelim.<\/p>\n<h4>Veritaban\u0131 \u015eemas\u0131<\/h4>\n<p>Hibernate, yukar\u0131daki varl\u0131k tan\u0131mlamalar\u0131na dayanarak a\u015fa\u011f\u0131daki veritaban\u0131 \u015femas\u0131n\u0131 olu\u015fturacakt\u0131r (varsay\u0131lan olarak):<\/p>\n<pre><code class=\"language-sql\">CREATE TABLE YAZARLAR (\n    id BIGINT NOT NULL AUTO_INCREMENT,\n    ad VARCHAR(255),\n    soyad VARCHAR(255),\n    PRIMARY KEY (id)\n);\n\nCREATE TABLE K\u0130TAPLAR (\n    id BIGINT NOT NULL AUTO_INCREMENT,\n    baslik VARCHAR(255),\n    yayin_yili INT,\n    PRIMARY KEY (id)\n);\n\nCREATE TABLE YAZAR_K\u0130TAP (\n    yazar_id BIGINT NOT NULL,\n    kitap_id BIGINT NOT NULL,\n    PRIMARY KEY (yazar_id, kitap_id),\n    FOREIGN KEY (yazar_id) REFERENCES YAZARLAR (id),\n    FOREIGN KEY (kitap_id) REFERENCES K\u0130TAPLAR (id)\n);<\/code><\/pre>\n<h4>Yazar Varl\u0131\u011f\u0131 (Author.java)<\/h4>\n<pre><code class=\"language-java\">package com.example.hibernate.entity;\n\nimport javax.persistence.*;\nimport java.util.HashSet;\nimport java.util.Set;\n\n@Entity\n@Table(name = \"YAZARLAR\")\npublic class Yazar {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @Column(name = \"ad\")\n    private String ad;\n\n    @Column(name = \"soyad\")\n    private String soyad;\n\n    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)\n    @JoinTable(\n        name = \"YAZAR_K\u0130TAP\",\n        joinColumns = @JoinColumn(name = \"yazar_id\"),\n        inverseJoinColumns = @JoinColumn(name = \"kitap_id\")\n    )\n    private Set<Kitap> kitaplar = new HashSet<>();\n\n    public Yazar() {\n    }\n\n    public Yazar(String ad, String soyad) {\n        this.ad = ad;\n        this.soyad = soyad;\n    }\n\n    \/\/ Getter ve Setter metotlar\u0131\n    public Long getId() { return id; }\n    public void setId(Long id) { this.id = id; }\n    public String getAd() { return ad; }\n    public void setAd(String ad) { this.ad = ad; }\n    public String getSoyad() { return soyad; }\n    public void setSoyad(String soyad) { this.soyad = soyad; }\n    public Set<Kitap> getKitaplar() { return kitaplar; }\n    public void setKitaplar(Set<Kitap> kitaplar) { this.kitaplar = kitaplar; }\n\n    \/\/ \u0130li\u015fki yard\u0131mc\u0131 metotlar\u0131\n    public void kitapEkle(Kitap kitap) {\n        this.kitaplar.add(kitap);\n        kitap.getYazarlar().add(this); \/\/ \u0130li\u015fkinin di\u011fer taraf\u0131n\u0131 da g\u00fcncelle\n    }\n\n    public void kitapCikar(Kitap kitap) {\n        this.kitaplar.remove(kitap);\n        kitap.getYazarlar().remove(this); \/\/ \u0130li\u015fkinin di\u011fer taraf\u0131n\u0131 da g\u00fcncelle\n    }\n\n    @Override\n    public String toString() {\n        return \"Yazar{\" +\n               \"id=\" + id +\n               \", ad='\" + ad + '\\'' +\n               \", soyad='\" + soyad + '\\'' +\n               '}';\n    }\n\n    \/\/ equals ve hashCode metotlar\u0131 (\u00f6nemli!)\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (!(o instanceof Yazar)) return false;\n        Yazar yazar = (Yazar) o;\n        return id != null && id.equals(yazar.id);\n    }\n\n    @Override\n    public int hashCode() {\n        return getClass().hashCode();\n    }\n}<\/code><\/pre>\n<h4>Kitap Varl\u0131\u011f\u0131 (Book.java)<\/h4>\n<pre><code class=\"language-java\">package com.example.hibernate.entity;\n\nimport javax.persistence.*;\nimport java.util.HashSet;\nimport java.util.Set;\n\n@Entity\n@Table(name = \"K\u0130TAPLAR\")\npublic class Kitap {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @Column(name = \"baslik\")\n    private String baslik;\n\n    @Column(name = \"yayin_yili\")\n    private int yayinYili;\n\n    @ManyToMany(mappedBy = \"kitaplar\", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)\n    private Set<Yazar> yazarlar = new HashSet<>();\n\n    public Kitap() {\n    }\n\n    public Kitap(String baslik, int yayinYili) {\n        this.baslik = baslik;\n        this.yayinYili = yayinYili;\n    }\n\n    \/\/ Getter ve Setter metotlar\u0131\n    public Long getId() { return id; }\n    public void setId(Long id) { this.id = id; }\n    public String getBaslik() { return baslik; }\n    public void setBaslik(String baslik) { this.baslik = baslik; }\n    public int getYayinYili() { return yayinYili; }\n    public void setYayinYili(int yayinYili) { this.yayinYili = yayinYili; }\n    public Set<Yazar> getYazarlar() { return yazarlar; }\n    public void setYazarlar(Set<Yazar> yazarlar) { this.yazarlar = yazarlar; }\n\n    \/\/ \u0130li\u015fki yard\u0131mc\u0131 metotlar\u0131\n    public void yazarEkle(Yazar yazar) {\n        this.yazarlar.add(yazar);\n        yazar.getKitaplar().add(this);\n    }\n\n    public void yazarCikar(Yazar yazar) {\n        this.yazarlar.remove(yazar);\n        yazar.getKitaplar().remove(this);\n    }\n\n    @Override\n    public String toString() {\n        return \"Kitap{\" +\n               \"id=\" + id +\n               \", baslik='\" + baslik + '\\'' +\n               \", yayinYili=\" + yayinYili +\n               '}';\n    }\n\n    \/\/ equals ve hashCode metotlar\u0131 (\u00f6nemli!)\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (!(o instanceof Kitap)) return false;\n        Kitap kitap = (Kitap) o;\n        return id != null && id.equals(kitap.id);\n    }\n\n    @Override\n    public int hashCode() {\n        return getClass().hashCode();\n    }\n}<\/code><\/pre>\n<h2>\u0130ki Y\u00f6nl\u00fc (Bidirectional) ve Tek Y\u00f6nl\u00fc (Unidirectional) Haritalamalar<\/h2>\n<p>\u00c7oka-\u00e7ok ili\u015fkiler tek y\u00f6nl\u00fc veya iki y\u00f6nl\u00fc olarak haritalanabilir.<\/p>\n<h3>Tek Y\u00f6nl\u00fc Haritalama<\/h3>\n<p>Tek y\u00f6nl\u00fc haritalamada, ili\u015fki sadece bir varl\u0131k s\u0131n\u0131f\u0131nda tan\u0131mlan\u0131r. \u00d6rne\u011fin, sadece <code>Yazar<\/code> s\u0131n\u0131f\u0131nda <code>Set<Kitap> kitaplar<\/code> koleksiyonu tan\u0131mlan\u0131r ve <code>Kitap<\/code> s\u0131n\u0131f\u0131nda <code>Set<Yazar> yazarlar<\/code> koleksiyonu bulunmaz.<\/p>\n<pre><code class=\"language-java\">public class Yazar {\n    \/\/ ... di\u011fer alanlar ...\n    @ManyToMany\n    @JoinTable(\n        name = \"YAZAR_K\u0130TAP\",\n        joinColumns = @JoinColumn(name = \"yazar_id\"),\n        inverseJoinColumns = @JoinColumn(name = \"kitap_id\")\n    )\n    private Set<Kitap> kitaplar = new HashSet<>();\n    \/\/ ...\n}\n\npublic class Kitap {\n    \/\/ ... di\u011fer alanlar ...\n    \/\/ Burada yazarlar koleksiyonu YOK\n    \/\/ ...\n}<\/code><\/pre>\n<p>Bu yakla\u015f\u0131m daha basittir ancak bir <code>Kitap<\/code> nesnesinden do\u011frudan ili\u015fkili yazarlar\u0131 sorgulaman\u0131za izin vermez. Bu durumda, ili\u015fkili yazarlar\u0131 almak i\u00e7in ayr\u0131 bir sorgu \u00e7al\u0131\u015ft\u0131rman\u0131z veya <code>Yazar<\/code> varl\u0131\u011f\u0131 \u00fczerinden sorgulama yapman\u0131z gerekir.<\/p>\n<h3>\u0130ki Y\u00f6nl\u00fc Haritalama ve Avantajlar\u0131<\/h3>\n<p>\u0130ki y\u00f6nl\u00fc haritalama, her iki varl\u0131k s\u0131n\u0131f\u0131nda da koleksiyonlar\u0131n tan\u0131mland\u0131\u011f\u0131 ve <code>mappedBy<\/code> kullan\u0131larak ili\u015fkinin bir taraf\u0131n\u0131n owning, di\u011fer taraf\u0131n\u0131n inverse olarak belirlendi\u011fi yakla\u015f\u0131md\u0131r. Yukar\u0131daki Yazar-Kitap \u00f6rne\u011fi iki y\u00f6nl\u00fcd\u00fcr.<br \/>\nAvantajlar\u0131:<br \/>\n*   <strong>Tam Gezinilebilirlik<\/strong>: Her iki varl\u0131ktan da ili\u015fkiyi kolayca gezinebilirsiniz (\u00f6rn. bir yazar\u0131n kitaplar\u0131n\u0131 veya bir kitab\u0131n yazarlar\u0131n\u0131).<br \/>\n*   <strong>Daha Anla\u015f\u0131l\u0131r Kod<\/strong>: \u0130li\u015fkiyi her iki taraftan da y\u00f6netmek, kodun daha sezgisel ve okunabilir olmas\u0131n\u0131 sa\u011flar.<br \/>\n*   <strong>Veri B\u00fct\u00fcnl\u00fc\u011f\u00fc<\/strong>: \u0130li\u015fki yard\u0131mc\u0131 metotlar\u0131 (\u00f6rn. <code>kitapEkle<\/code>, <code>yazarEkle<\/code>) kullanarak her iki taraf\u0131 da g\u00fcncel tutmak, veri tutars\u0131zl\u0131\u011f\u0131n\u0131 \u00f6nler.<\/p>\n<p>\u0130ki y\u00f6nl\u00fc ili\u015fkilerde, yard\u0131mc\u0131 metotlar (helper methods) yazmak en iyi uygulamad\u0131r. Bu metotlar, ili\u015fkinin her iki taraf\u0131ndaki koleksiyonlar\u0131 da g\u00fcncelleyerek veri tutarl\u0131l\u0131\u011f\u0131n\u0131 sa\u011flar. \u00d6rne\u011fin, bir <code>Yazar<\/code>&#8216;a bir <code>Kitap<\/code> ekledi\u011finizde, <code>Kitap<\/code>&#8216;\u0131n <code>yazarlar<\/code> koleksiyonuna da ilgili <code>Yazar<\/code>&#8216;\u0131 eklemelisiniz.<\/p>\n<h2>CRUD Operasyonlar\u0131 ve \u0130li\u015fki Y\u00f6netimi<\/h2>\n<p>Hibernate ile \u00e7oka-\u00e7ok ili\u015fkileri y\u00f6netmek, temel CRUD operasyonlar\u0131 \u00fczerinden yap\u0131l\u0131r.<\/p>\n<h3>Yeni \u0130li\u015fkiler Olu\u015fturma<\/h3>\n<p>Yeni bir yazar ve kitap olu\u015fturup aralar\u0131nda ili\u015fki kurmak i\u00e7in:<\/p>\n<pre><code class=\"language-java\">\/\/ Yazar ve Kitap nesneleri olu\u015fturma\nYazar yazar1 = new Yazar(\"Ahmet\", \"\u00dcmit\");\nKitap kitap1 = new Kitap(\"\u0130stanbul Hat\u0131ras\u0131\", 2010);\nKitap kitap2 = new Kitap(\"Beyo\u011flu Rapsodisi\", 2003);\n\n\/\/ \u0130li\u015fkileri kurma (yard\u0131mc\u0131 metotlar ile)\nyazar1.kitapEkle(kitap1);\nyazar1.kitapEkle(kitap2);\n\n\/\/ Veritaban\u0131na kaydetme\nSession session = sessionFactory.openSession();\nTransaction transaction = session.beginTransaction();\n\nsession.persist(yazar1); \/\/ CascadeType.PERSIST sayesinde kitaplar da kaydedilir\n\ntransaction.commit();\nsession.close();<\/code><\/pre>\n<p><code>CascadeType.PERSIST<\/code> kullan\u0131ld\u0131\u011f\u0131nda, <code>yazar1<\/code> kaydedildi\u011finde ili\u015fkili <code>kitap1<\/code> ve <code>kitap2<\/code> nesneleri de otomatik olarak kaydedilir.<\/p>\n<h3>\u0130li\u015fkileri G\u00fcncelleme (Ekleme\/\u00c7\u0131karma)<\/h3>\n<p>Mevcut bir yazara yeni bir kitap eklemek veya bir yazardan bir kitab\u0131 \u00e7\u0131karmak i\u00e7in:<\/p>\n<pre><code class=\"language-java\">Session session = sessionFactory.openSession();\nTransaction transaction = session.beginTransaction();\n\n\/\/ Mevcut yazar\u0131 ve kitab\u0131 al\nYazar yazar = session.find(Yazar.class, 1L); \/\/ ID'si 1 olan yazar\u0131 al\nKitap yeniKitap = new Kitap(\"Elveda G\u00fczel Vatan\u0131m\", 2015);\nsession.persist(yeniKitap); \/\/ Yeni kitab\u0131 kaydet\n\n\/\/ \u0130li\u015fkiyi ekle\nyazar.kitapEkle(yeniKitap);\n\n\/\/ \u0130li\u015fkiyi veritaban\u0131na yans\u0131t (yazar nesnesi g\u00fcncellendi\u011fi i\u00e7in merge yeterli)\nsession.merge(yazar);\n\ntransaction.commit();\nsession.close();<\/code><\/pre>\n<p>\u0130li\u015fki \u00e7\u0131karmak i\u00e7in <code>yazar.kitapCikar(kitap)<\/code> yard\u0131mc\u0131 metodunu kullanmak yeterlidir. Hibernate, <code>merge<\/code> i\u015flemi s\u0131ras\u0131nda koleksiyon de\u011fi\u015fikliklerini alg\u0131lay\u0131p ba\u011flant\u0131 tablosunu g\u00fcnceller.<\/p>\n<h3>\u0130li\u015fkili Varl\u0131klar\u0131 Silme ve Cascade T\u00fcrleri<\/h3>\n<p><code>@ManyToMany<\/code> ili\u015fkilerde <code>cascade<\/code> \u00f6zelli\u011fi, bir varl\u0131k \u00fczerinde yap\u0131lan bir i\u015flemin (persist, merge, remove) ili\u015fkili varl\u0131klar \u00fczerinde de otomatik olarak uygulan\u0131p uygulanmayaca\u011f\u0131n\u0131 kontrol eder.<\/p>\n<h4>CascadeType.ALL<\/h4>\n<p>Bir varl\u0131k silindi\u011finde, ili\u015fkili t\u00fcm varl\u0131klar\u0131n da silinmesini sa\u011flar. <strong>\u00c7oka-\u00e7ok ili\u015fkilerde <code>CascadeType.ALL<\/code> veya <code>CascadeType.REMOVE<\/code> kullan\u0131rken \u00e7ok dikkatli olunmal\u0131d\u0131r.<\/strong> \u00c7\u00fcnk\u00fc bir yazar silindi\u011finde, o yazar\u0131n yazd\u0131\u011f\u0131 kitaplar\u0131n da silinmesi istenmeyebilir (kitap ba\u015fka yazarlar taraf\u0131ndan da yaz\u0131lm\u0131\u015f olabilir veya tek ba\u015f\u0131na var olmaya devam etmelidir). Genellikle, \u00e7oka-\u00e7ok ili\u015fkilerde <code>REMOVE<\/code> cascade&#8217;i kullan\u0131lmaz, sadece ba\u011flant\u0131 tablosundaki ili\u015fkinin silinmesi istenir.<\/p>\n<h4>CascadeType.PERSIST ve CascadeType.MERGE<\/h4>\n<p>Bu t\u00fcrler, yeni bir varl\u0131k kaydedildi\u011finde veya mevcut bir varl\u0131k g\u00fcncellendi\u011finde, ili\u015fkili varl\u0131klar\u0131n da kaydedilmesini\/g\u00fcncellenmesini sa\u011flar. Genellikle \u00e7oka-\u00e7ok ili\u015fkiler i\u00e7in g\u00fcvenli ve kullan\u0131\u015fl\u0131 olan <code>PERSIST<\/code> ve <code>MERGE<\/code> cascade t\u00fcrleridir. Bu, yeni bir yazar kaydederken onunla ili\u015fkili yeni kitaplar\u0131n da otomatik kaydedilmesini sa\u011flar.<\/p>\n<h4>CascadeType.REMOVE ve Orphan Removal<\/h4>\n<p><code>CascadeType.REMOVE<\/code> bir varl\u0131k silindi\u011finde ili\u015fkili varl\u0131klar\u0131 da siler. <code>orphanRemoval = true<\/code> ise, bir koleksiyondan bir alt varl\u0131k kald\u0131r\u0131ld\u0131\u011f\u0131nda, bu alt varl\u0131\u011f\u0131n da veritaban\u0131ndan silinmesini sa\u011flar. Ancak, \u00e7oka-\u00e7ok ili\u015fkilerde bu genellikle istenmez \u00e7\u00fcnk\u00fc ili\u015fkili varl\u0131klar genellikle ba\u011f\u0131ms\u0131z bir ya\u015fam d\u00f6ng\u00fcs\u00fcne sahiptir. Bir yazar silindi\u011finde, yazd\u0131\u011f\u0131 kitaplar\u0131n da silinmesini istemeyiz; sadece yazar ile kitap aras\u0131ndaki ili\u015fkinin (ba\u011flant\u0131 tablosundaki kayd\u0131n) silinmesini isteriz. Bu nedenle, \u00e7oka-\u00e7ok ili\u015fkilerde genellikle sadece <code>PERSIST<\/code> ve <code>MERGE<\/code> kullan\u0131l\u0131r, <code>REMOVE<\/code> kullan\u0131lmaz. \u0130li\u015fkiyi silmek i\u00e7in sadece koleksiyondan eleman\u0131 \u00e7\u0131karmak ve ard\u0131ndan <code>merge<\/code> i\u015flemi yapmak yeterlidir. Hibernate, ba\u011flant\u0131 tablosundaki ilgili kayd\u0131 otomatik olarak siler.<\/p>\n<h2>Performans Optimizasyonlar\u0131 ve En \u0130yi Uygulamalar<\/h2>\n<p>Hibernate ile \u00e7oka-\u00e7ok ili\u015fkileri kullan\u0131rken performans ve verimlilik \u00f6nemlidir.<\/p>\n<h3>Fetch T\u00fcrleri: Lazy ve Eager Y\u00fckleme<\/h3>\n<p><code>@ManyToMany<\/code> ili\u015fkilerde varsay\u0131lan y\u00fckleme stratejisi <code>FetchType.LAZY<\/code>&#8216;dir.<br \/>\n*   <strong><code>FetchType.LAZY<\/code> (Tembel Y\u00fckleme)<\/strong>: \u0130li\u015fkili veriler, yaln\u0131zca onlara eri\u015fildi\u011finde (yani koleksiyonun getter metodu \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda) veritaban\u0131ndan y\u00fcklenir. Bu, N+1 sorgu sorununa yol a\u00e7abilir ancak gereksiz veri y\u00fcklemesini \u00f6nleyerek ba\u015flang\u0131\u00e7ta daha iyi performans sa\u011flar. Genellikle tercih edilen y\u00f6ntemdir.<br \/>\n*   <strong><code>FetchType.EAGER<\/code> (Aceleci Y\u00fckleme)<\/strong>: \u0130li\u015fkili veriler, ana varl\u0131k y\u00fcklendi\u011finde otomatik olarak birlikte y\u00fcklenir. Bu, daha az sorgu anlam\u0131na gelebilir ancak gereksiz yere b\u00fcy\u00fck miktarda veri y\u00fckleyebilir ve performans\u0131 d\u00fc\u015f\u00fcrebilir, \u00f6zellikle ili\u015fkili koleksiyonlar b\u00fcy\u00fckse.<\/p>\n<h3>N+1 Problemi ve \u00c7\u00f6z\u00fcmleri<\/h3>\n<p><code>FetchType.LAZY<\/code> kullan\u0131ld\u0131\u011f\u0131nda, bir liste varl\u0131\u011f\u0131 sorgulay\u0131p her bir varl\u0131\u011f\u0131n ili\u015fkili koleksiyonuna eri\u015fti\u011finizde &#8220;N+1 problemi&#8221; ile kar\u015f\u0131la\u015fabilirsiniz. Bu, ana varl\u0131klar\u0131 almak i\u00e7in 1 sorgu, ard\u0131ndan her bir ana varl\u0131k i\u00e7in ili\u015fkili koleksiyonu almak i\u00e7in N adet ayr\u0131 sorgu \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 anlam\u0131na gelir. Bu, \u00f6zellikle b\u00fcy\u00fck veri k\u00fcmeleri i\u00e7in ciddi performans sorunlar\u0131na yol a\u00e7abilir.<\/p>\n<h4>Join Fetch Kullan\u0131m\u0131<\/h4>\n<p>N+1 sorununu \u00e7\u00f6zmenin en yayg\u0131n yolu <code>JOIN FETCH<\/code> kullanmakt\u0131r. Bu, ili\u015fkili verileri ana sorguyla birlikte tek bir JOIN sorgusu ile y\u00fcklemeyi sa\u011flar.<\/p>\n<pre><code class=\"language-java\">\/\/ T\u00fcm yazarlar\u0131 ve onlar\u0131n kitaplar\u0131n\u0131 tek bir sorgu ile y\u00fckle\nList<Yazar> yazarlar = session.createQuery(\"SELECT DISTINCT y FROM Yazar y JOIN FETCH y.kitaplar\", Yazar.class)\n                              .getResultList();<\/code><\/pre>\n<p><code>DISTINCT<\/code> anahtar kelimesi, JOIN i\u015flemi nedeniyle tekrarlanan <code>Yazar<\/code> nesnelerinin \u00f6nlenmesi i\u00e7in kullan\u0131l\u0131r.<\/p>\n<h4>@BatchSize ve @Fetch(FetchMode.SUBSELECT)<\/h4>\n<p>*   <strong><code>@BatchSize<\/code><\/strong>: Bu annotasyon, ili\u015fkili koleksiyonlar\u0131 belirli bir boyuttaki gruplar halinde y\u00fckleyerek N+1 sorununu hafifletir. \u00d6rne\u011fin, <code>@BatchSize(size = 10)<\/code> ile 10 yazar\u0131n kitaplar\u0131 tek bir sorguda y\u00fcklenebilir.<\/p>\n<pre><code class=\"language-java\">@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)\n    @JoinTable(...)\n    @BatchSize(size = 10) \/\/ 10'arl\u0131 gruplar halinde y\u00fckle\n    private Set<Kitap> kitaplar = new HashSet<>();<\/code><\/pre>\n<p>*   <strong><code>@Fetch(FetchMode.SUBSELECT)<\/code><\/strong>: Bu mod, ili\u015fkili koleksiyonlar\u0131, ana varl\u0131klar\u0131 y\u00fckleyen sorgunun WHERE ko\u015fulunda bir alt sorgu kullanarak y\u00fckler.<\/p>\n<pre><code class=\"language-java\">@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)\n    @JoinTable(...)\n    @Fetch(FetchMode.SUBSELECT)\n    private Set<Kitap> kitaplar = new HashSet<>();<\/code><\/pre>\n<p>Bu iki y\u00f6ntem de N+1 sorununu tamamen \u00e7\u00f6zmese de sorgu say\u0131s\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde azaltarak performans\u0131 art\u0131rabilir.<\/p>\n<h3>equals() ve hashCode() Metotlar\u0131n\u0131n \u00d6nemi<\/h3>\n<p>Hibernate&#8217;te, koleksiyon tabanl\u0131 ili\u015fkilerde (\u00f6zellikle <code>Set<\/code> kullan\u0131ld\u0131\u011f\u0131nda) varl\u0131k s\u0131n\u0131flar\u0131nda <code>equals()<\/code> ve <code>hashCode()<\/code> metotlar\u0131n\u0131 do\u011fru bir \u015fekilde uygulamak kritik \u00f6neme sahiptir.<br \/>\n*   <code>Set<\/code> gibi koleksiyonlar, elemanlar\u0131n benzersizli\u011fini ve e\u015fitli\u011fini kontrol etmek i\u00e7in bu metotlar\u0131 kullan\u0131r.<br \/>\n*   Bir varl\u0131\u011f\u0131n kimli\u011fi (ID&#8217;si) veritaban\u0131na kaydedilene kadar olu\u015fmayabilir. Bu nedenle, <code>equals()<\/code> ve <code>hashCode()<\/code> metotlar\u0131n\u0131 sadece ID alan\u0131na g\u00f6re uygulamak, varl\u0131klar kal\u0131c\u0131 hale getirilmeden \u00f6nce veya sonra farkl\u0131 davran\u0131\u015flara yol a\u00e7abilir.<br \/>\n*   En iyi uygulama, <code>equals()<\/code> metodunda varl\u0131\u011f\u0131n ID&#8217;sini kullanmak, ancak ID hen\u00fcz atanmam\u0131\u015fsa (yani yeni bir varl\u0131ksa) referans e\u015fitli\u011fini kontrol etmektir. <code>hashCode()<\/code> metodu i\u00e7in ise sabit bir de\u011fer d\u00f6nd\u00fcrmek veya <code>getClass().hashCode()<\/code> kullanmak g\u00fcvenli bir ba\u015flang\u0131\u00e7 olabilir, ancak bu konuda daha geli\u015fmi\u015f stratejiler de mevcuttur. Yukar\u0131daki \u00f6rneklerde, ID&#8217;nin null olup olmad\u0131\u011f\u0131n\u0131 kontrol ederek g\u00fcvenli bir <code>equals<\/code> ve <code>hashCode<\/code> uygulamas\u0131 g\u00f6sterilmi\u015ftir.<\/p>\n<h2>Ba\u011flant\u0131 Tablosunda Ek Nitelikler (Extra Attributes)<\/h2>\n<p>Bazen \u00e7oka-\u00e7ok ili\u015fkisi sadece iki varl\u0131\u011f\u0131n ba\u011flant\u0131s\u0131n\u0131 de\u011fil, ayn\u0131 zamanda bu ba\u011flant\u0131n\u0131n kendisine ait ek bilgileri de i\u00e7erebilir. \u00d6rne\u011fin, &#8220;Yazar&#8221; ve &#8220;Kitap&#8221; ili\u015fkisinde, bir yazar\u0131n bir kitab\u0131 ne zaman yazd\u0131\u011f\u0131 (<code>yazma_tarihi<\/code>) gibi ek bir nitelik ba\u011flant\u0131 tablosunda saklanabilir. Bu durumda, standart <code>@ManyToMany<\/code> haritalamas\u0131 yeterli olmaz.<\/p>\n<h3>@ManyToMany yerine @OneToMany\/@ManyToOne Kullan\u0131m\u0131<\/h3>\n<p>Ba\u011flant\u0131 tablosunda ek nitelikler oldu\u011funda, \u00e7oka-\u00e7ok ili\u015fkisi asl\u0131nda iki adet bire-\u00e7ok ve \u00e7ok-bire ili\u015fkisine d\u00f6n\u00fc\u015f\u00fcr. Bu durumda, ba\u011flant\u0131 tablosunu temsil eden ayr\u0131 bir &#8220;ara varl\u0131k&#8221; (join entity veya association entity) olu\u015fturulur.<\/p>\n<h3>Ara Varl\u0131k Tasar\u0131m\u0131<\/h3>\n<p>\u00d6rnek olarak, <code>YazarKitap<\/code> ad\u0131nda bir ara varl\u0131k olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-java\">\/\/ YazarKitap.java\npackage com.example.hibernate.entity;\n\nimport javax.persistence.*;\nimport java.io.Serializable;\nimport java.time.LocalDate;\n\n@Entity\n@Table(name = \"YAZAR_K\u0130TAP\")\npublic class YazarKitap implements Serializable { \/\/ Serializable olmas\u0131 Composite Key i\u00e7in \u00f6nemli\n\n    @EmbeddedId\n    private YazarKitapId id; \/\/ Bile\u015fik anahtar i\u00e7in g\u00f6m\u00fcl\u00fc ID\n\n    @ManyToOne(fetch = FetchType.LAZY)\n    @MapsId(\"yazarId\") \/\/ YazarKitapId'deki yazarId alan\u0131na haritala\n    @JoinColumn(name = \"yazar_id\")\n    private Yazar yazar;\n\n    @ManyToOne(fetch = FetchType.LAZY)\n    @MapsId(\"kitapId\") \/\/ YazarKitapId'deki kitapId alan\u0131na haritala\n    @JoinColumn(name = \"kitap_id\")\n    private Kitap kitap;\n\n    @Column(name = \"yazma_tarihi\")\n    private LocalDate yazmaTarihi;\n\n    public YazarKitap() {\n    }\n\n    public YazarKitap(Yazar yazar, Kitap kitap, LocalDate yazmaTarihi) {\n        this.yazar = yazar;\n        this.kitap = kitap;\n        this.yazmaTarihi = yazmaTarihi;\n        this.id = new YazarKitapId(yazar.getId(), kitap.getId());\n    }\n\n    \/\/ Getter ve Setter metotlar\u0131\n    public YazarKitapId getId() { return id; }\n    public void setId(YazarKitapId id) { this.id = id; }\n    public Yazar getYazar() { return yazar; }\n    public void setYazar(Yazar yazar) { this.yazar = yazar; }\n    public Kitap getKitap() { return kitap; }\n    public void setKitap(Kitap kitap) { this.kitap = kitap; }\n    public LocalDate getYazmaTarihi() { return yazmaTarihi; }\n    public void setYazmaTarihi(LocalDate yazmaTarihi) { this.yazmaTarihi = yazmaTarihi; }\n\n    \/\/ equals ve hashCode (YazarKitapId taraf\u0131ndan y\u00f6netilir)\n}<\/code><\/pre>\n<pre><code class=\"language-java\">\/\/ YazarKitapId.java (Bile\u015fik Anahtar S\u0131n\u0131f\u0131)\npackage com.example.hibernate.entity;\n\nimport javax.persistence.Embeddable;\nimport java.io.Serializable;\nimport java.util.Objects;\n\n@Embeddable\npublic class YazarKitapId implements Serializable {\n\n    private Long yazarId;\n    private Long kitapId;\n\n    public YazarKitapId() {\n    }\n\n    public YazarKitapId(Long yazarId, Long kitapId) {\n        this.yazarId = yazarId;\n        this.kitapId = kitapId;\n    }\n\n    \/\/ Getter ve Setter metotlar\u0131\n    public Long getYazarId() { return yazarId; }\n    public void setYazarId(Long yazarId) { this.yazarId = yazarId; }\n    public Long getKitapId() { return kitapId; }\n    public void setKitapId(Long kitapId) { this.kitapId = kitapId; }\n\n    \/\/ equals ve hashCode metotlar\u0131 (Composite Key i\u00e7in zorunlu)\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        YazarKitapId that = (YazarKitapId) o;\n        return Objects.equals(yazarId, that.yazarId) &&\n               Objects.equals(kitapId, that.kitapId);\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(yazarId, kitapId);\n    }\n}<\/code><\/pre>\n<p>Bu durumda, <code>Yazar<\/code> ve <code>Kitap<\/code> varl\u0131klar\u0131 <code>@ManyToMany<\/code> yerine <code>@OneToMany<\/code> ili\u015fkilerini <code>YazarKitap<\/code> varl\u0131\u011f\u0131na sahip olacak \u015fekilde g\u00fcncellenir:<\/p>\n<pre><code class=\"language-java\">\/\/ Yazar.java g\u00fcncellendi\npublic class Yazar {\n    \/\/ ...\n    @OneToMany(mappedBy = \"yazar\", cascade = CascadeType.ALL, orphanRemoval = true)\n    private Set<YazarKitap> yazarKitaplari = new HashSet<>();\n    \/\/ ...\n}\n\n\/\/ Kitap.java g\u00fcncellendi\npublic class Kitap {\n    \/\/ ...\n    @OneToMany(mappedBy = \"kitap\", cascade = CascadeType.ALL, orphanRemoval = true)\n    private Set<YazarKitap> yazarKitaplari = new HashSet<>();\n    \/\/ ...\n}<\/code><\/pre>\n<p>Bu yakla\u015f\u0131m, ba\u011flant\u0131 tablosundaki ek nitelikleri y\u00f6netme esnekli\u011fi sa\u011flar ve daha karma\u015f\u0131k \u00e7oka-\u00e7ok ili\u015fkileri modellemek i\u00e7in g\u00fc\u00e7l\u00fc bir y\u00f6ntemdir. Ancak, kodun karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 art\u0131r\u0131r ve sadece ek nitelikler gerekti\u011finde kullan\u0131lmal\u0131d\u0131r.<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>Hibernate, \u00e7oka-\u00e7ok ili\u015fkileri y\u00f6netmek i\u00e7in g\u00fc\u00e7l\u00fc ve esnek mekanizmalar sunar. <code>@ManyToMany<\/code> ve <code>@JoinTable<\/code> annotasyonlar\u0131, standart ba\u011flant\u0131 tablosu haritalamalar\u0131n\u0131 kolayla\u015ft\u0131r\u0131rken, <code>mappedBy<\/code> kullan\u0131m\u0131 ili\u015fkinin y\u00f6netimini tek bir tarafa b\u0131rakarak tutarl\u0131l\u0131\u011f\u0131 sa\u011flar. Tek y\u00f6nl\u00fc ve iki y\u00f6nl\u00fc haritalama se\u00e7enekleri, uygulaman\u0131z\u0131n ihtiya\u00e7lar\u0131na g\u00f6re esneklik sunar.<\/p>\n<p>Performans optimizasyonlar\u0131, \u00f6zellikle <code>FetchType.LAZY<\/code> ve N+1 problemi gibi konular, b\u00fcy\u00fck \u00f6l\u00e7ekli uygulamalar i\u00e7in hayati \u00f6neme sahiptir. <code>JOIN FETCH<\/code>, <code>@BatchSize<\/code> gibi teknikler bu sorunlar\u0131n \u00fcstesinden gelmek i\u00e7in kullan\u0131labilir. Ayr\u0131ca, <code>equals()<\/code> ve <code>hashCode()<\/code> metotlar\u0131n\u0131n do\u011fru uygulanmas\u0131, koleksiyon tabanl\u0131 ili\u015fkilerde beklenen davran\u0131\u015f\u0131 sa\u011flamak i\u00e7in vazge\u00e7ilmezdir.<\/p>\n<p>Ba\u011flant\u0131 tablosunda ek nitelikler gerekti\u011finde, <code>@ManyToMany<\/code> yerine ara bir varl\u0131k olu\u015fturarak <code>@OneToMany<\/code> ve <code>@ManyToOne<\/code> ili\u015fkilerini kullanmak, daha karma\u015f\u0131k veri modellerini ba\u015far\u0131yla haritalaman\u0131n anahtar\u0131d\u0131r. Do\u011fru tasar\u0131m ve dikkatli uygulama ile Hibernate, \u00e7oka-\u00e7ok ili\u015fkilerinizi verimli ve hatas\u0131z bir \u015fekilde y\u00f6netmenizi sa\u011flayarak sa\u011flam ve \u00f6l\u00e7eklenebilir uygulamalar geli\u015ftirmenize olanak tan\u0131r.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Hibernate&#8217;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri\nGiri\u015f: \u00c7oka-\u00c7ok \u0130li\u015fkiler ve Veritaban\u0131 Tasar\u0131m","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-31540","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Hibernate&#039;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Hibernate&#039;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri\" \/>\n<meta property=\"og:description\" content=\"Hibernate&#039;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri Giri\u015f: \u00c7oka-\u00c7ok \u0130li\u015fkiler ve Veritaban\u0131 Tasar\u0131m\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-10T23:41:02+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Hibernate&#8217;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri\",\"datePublished\":\"2025-10-10T23:41:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/\"},\"wordCount\":2925,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/\",\"name\":\"Hibernate'te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-10T23:41:02+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Hibernate&#8217;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Hibernate'te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/","og_locale":"tr_TR","og_type":"article","og_title":"Hibernate'te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri","og_description":"Hibernate'te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri Giri\u015f: \u00c7oka-\u00c7ok \u0130li\u015fkiler ve Veritaban\u0131 Tasar\u0131m","og_url":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-10T23:41:02+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"22 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Hibernate&#8217;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri","datePublished":"2025-10-10T23:41:02+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/"},"wordCount":2925,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/","url":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/","name":"Hibernate'te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-10T23:41:02+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/hibernatete-coka-cok-iliskiler-baglanti-tablolari-ve-detayli-haritalama-stratejileri\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Hibernate&#8217;te \u00c7oka-\u00c7ok \u0130li\u015fkiler: Ba\u011flant\u0131 Tablolar\u0131 ve Detayl\u0131 Haritalama Stratejileri"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31540","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31540"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31540\/revisions"}],"predecessor-version":[{"id":31541,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31540\/revisions\/31541"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31540"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31540"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}