{"id":35976,"date":"2025-12-06T09:40:44","date_gmt":"2025-12-06T06:40:44","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=35976"},"modified":"2025-12-06T09:40:44","modified_gmt":"2025-12-06T06:40:44","slug":"hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/","title":{"rendered":"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme"},"content":{"rendered":"<p><body><\/p>\n<h2>Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme<\/h2>\n<h3>Giri\u015f: Hibernate ve Varl\u0131k Y\u00f6netimi<\/h3>\n<p>Modern Java uygulamalar\u0131nda veritaban\u0131 etkile\u015fimini kolayla\u015ft\u0131ran en g\u00fc\u00e7l\u00fc ara\u00e7lardan biri Hibernate&#8217;tir. Bir Object-Relational Mapping (ORM) \u00e7er\u00e7evesi olarak Hibernate, Java nesneleri ile ili\u015fkisel veritaban\u0131 tablolar\u0131 aras\u0131nda bir k\u00f6pr\u00fc g\u00f6revi g\u00f6r\u00fcr. Bu k\u00f6pr\u00fc sayesinde geli\u015ftiriciler, SQL sorgular\u0131 yazmak yerine Java nesneleri \u00fczerinde i\u015flem yaparak veritaban\u0131 manip\u00fclasyonu ger\u00e7ekle\u015ftirebilirler. Hibernate, JPA (Java Persistence API) spesifikasyonunun pop\u00fcler bir implementasyonudur ve veritaban\u0131 i\u015flemlerini y\u00f6netmek i\u00e7in bir dizi g\u00fc\u00e7l\u00fc API sunar. Bu API&#8217;lerin temelini, veritaban\u0131 ile etkile\u015fimin merkezi noktas\u0131 olan <code>Session<\/code> veya <code>EntityManager<\/code> (JPA terminolojisinde) nesnesi olu\u015fturur.<\/p>\n<p>Bir uygulaman\u0131n performans\u0131 ve veri tutarl\u0131l\u0131\u011f\u0131, varl\u0131klar\u0131n (entity) ya\u015fam d\u00f6ng\u00fcs\u00fcn\u00fcn do\u011fru bir \u015fekilde y\u00f6netilmesine ba\u011fl\u0131d\u0131r. Hibernate&#8217;te varl\u0131klar\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fc, <code>Session<\/code> nesnesi taraf\u0131ndan sa\u011flanan \u00e7e\u015fitli metotlar arac\u0131l\u0131\u011f\u0131yla kontrol edilir. Bu metotlar aras\u0131nda <code>save<\/code>, <code>persist<\/code>, <code>update<\/code>, <code>merge<\/code> ve <code>saveOrUpdate<\/code> en s\u0131k kullan\u0131lanlard\u0131r. Her bir metot, varl\u0131\u011f\u0131n mevcut durumuna (state) g\u00f6re farkl\u0131 davran\u0131\u015flar sergiler ve belirli senaryolar i\u00e7in optimize edilmi\u015ftir. Bu makalede, bu metotlar\u0131n her birini derinlemesine inceleyecek, aralar\u0131ndaki farklar\u0131, kullan\u0131m senaryolar\u0131n\u0131 ve dikkat edilmesi gereken noktalar\u0131 \u00f6rnek kodlarla a\u00e7\u0131klayaca\u011f\u0131z. Amac\u0131m\u0131z, geli\u015ftiricilerin bu metotlar\u0131 do\u011fru ve etkin bir \u015fekilde kullanarak Hibernate uygulamalar\u0131n\u0131 daha sa\u011flam ve verimli hale getirmelerine yard\u0131mc\u0131 olmakt\u0131r.<\/p>\n<h3>Hibernate Varl\u0131k Durumlar\u0131 (Entity States)<\/h3>\n<p>Hibernate&#8217;in varl\u0131k y\u00f6netimi metotlar\u0131n\u0131 anlamak i\u00e7in \u00f6ncelikle bir varl\u0131\u011f\u0131n sahip olabilece\u011fi farkl\u0131 durumlar\u0131 kavramak esast\u0131r. Bir varl\u0131k, ya\u015fam d\u00f6ng\u00fcs\u00fc boyunca \u00fc\u00e7 ana durumda bulunabilir:<\/p>\n<h4>Transient (Ge\u00e7ici) Durum<\/h4>\n<p>Bir varl\u0131k nesnesi, <code>new<\/code> anahtar kelimesiyle olu\u015fturuldu\u011funda ve hen\u00fcz bir Hibernate <code>Session<\/code>&#8216;\u0131 ile ili\u015fkilendirilmedi\u011finde bu durumdad\u0131r. Bu durumda varl\u0131\u011f\u0131n veritaban\u0131nda kar\u015f\u0131l\u0131\u011f\u0131 yoktur ve bir kimlik (ID) de\u011feri atanmam\u0131\u015ft\u0131r (e\u011fer ID veritaban\u0131 taraf\u0131ndan otomatik olu\u015fturulacaksa). Transient durumdaki bir varl\u0131k \u00fczerinde yap\u0131lan de\u011fi\u015fiklikler, veritaban\u0131na yans\u0131t\u0131lmaz.<\/p>\n<p><strong>\u00d6rnek:<\/strong><\/p>\n<pre><code class=\"language-java\">User user = new User(\"Alice\", \"alice@example.com\"); \/\/ Transient durumda<\/code><\/pre>\n<h4>Persistent (Kal\u0131c\u0131\/Y\u00f6netilen) Durum<\/h4>\n<p>Bir varl\u0131k, bir <code>Session<\/code> ile ili\u015fkilendirildi\u011finde ve o <code>Session<\/code> taraf\u0131ndan y\u00f6netildi\u011finde persistent durumdad\u0131r. Bu, varl\u0131\u011f\u0131n veritaban\u0131nda bir kar\u015f\u0131l\u0131\u011f\u0131 oldu\u011fu ve bir kimlik (ID) de\u011ferine sahip oldu\u011fu anlam\u0131na gelir. Persistent durumdaki bir varl\u0131k \u00fczerinde yap\u0131lan de\u011fi\u015fiklikler, <code>Session<\/code>&#8216;\u0131n <code>flush<\/code> edilmesi veya <code>commit<\/code> edilmesi durumunda otomatik olarak veritaban\u0131na senkronize edilir (dirty checking mekanizmas\u0131 sayesinde). Bu varl\u0131klar, <code>Session<\/code>&#8216;\u0131n \u00f6nbelle\u011finde (first-level cache) tutulur.<\/p>\n<p><strong>\u00d6rnek:<\/strong><\/p>\n<pre><code class=\"language-java\">User user = new User(\"Bob\", \"bob@example.com\");\nsession.save(user); \/\/ user art\u0131k persistent durumda\n\/\/ user \u00fczerinde yap\u0131lan de\u011fi\u015fiklikler session.flush() veya commit() ile veritaban\u0131na yans\u0131r<\/code><\/pre>\n<h4>Detached (Ayr\u0131k) Durum<\/h4>\n<p>Bir varl\u0131k, daha \u00f6nce persistent durumdayken ili\u015fkili oldu\u011fu <code>Session<\/code> kapat\u0131ld\u0131\u011f\u0131nda veya <code>Session<\/code>&#8216;dan a\u00e7\u0131k\u00e7a ayr\u0131ld\u0131\u011f\u0131nda (\u00f6rne\u011fin <code>session.evict(entity)<\/code> metoduyla) detached duruma ge\u00e7er. Detached durumdaki bir varl\u0131k, hala bir kimlik (ID) de\u011ferine sahiptir ve veritaban\u0131nda bir kar\u015f\u0131l\u0131\u011f\u0131 vard\u0131r, ancak art\u0131k bir <code>Session<\/code> taraf\u0131ndan y\u00f6netilmemektedir. Bu durumda yap\u0131lan de\u011fi\u015fiklikler otomatik olarak veritaban\u0131na yans\u0131t\u0131lmaz. Detached bir varl\u0131\u011f\u0131 tekrar persistent duruma getirmek i\u00e7in belirli Hibernate metotlar\u0131 kullan\u0131lmal\u0131d\u0131r.<\/p>\n<p><strong>\u00d6rnek:<\/strong><\/p>\n<pre><code class=\"language-java\">User user = session.get(User.class, 1L); \/\/ user persistent durumda\nsession.close(); \/\/ Session kapand\u0131\u011f\u0131nda user detached duruma ge\u00e7er\nuser.setEmail(\"new_bob@example.com\"); \/\/ Bu de\u011fi\u015fiklik veritaban\u0131na otomatik yans\u0131maz<\/code><\/pre>\n<p>Bu \u00fc\u00e7 durum, Hibernate&#8217;in varl\u0131k y\u00f6netimi metotlar\u0131n\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 anlaman\u0131n temelidir. \u015eimdi, bu metotlar\u0131 detayl\u0131 olarak inceleyelim.<\/p>\n<h3><code>save()<\/code> Metodu<\/h3>\n<p><code>save()<\/code> metodu, bir <code>Transient<\/code> durumdaki varl\u0131\u011f\u0131 <code>Persistent<\/code> duruma ge\u00e7irmek i\u00e7in kullan\u0131l\u0131r. Bu metot, Hibernate&#8217;e \u00f6zg\u00fc bir metottur ve JPA spesifikasyonunda do\u011frudan bir kar\u015f\u0131l\u0131\u011f\u0131 yoktur (JPA&#8217;daki kar\u015f\u0131l\u0131\u011f\u0131 <code>persist()<\/code> metodudur).<\/p>\n<h4>Davran\u0131\u015f ve \u00d6zellikler<\/h4>\n<p>*   <strong>Transient&#8217;tan Persistent&#8217;a:<\/strong> <code>save()<\/code> metodu, veritaban\u0131nda hen\u00fcz bir kar\u015f\u0131l\u0131\u011f\u0131 olmayan <code>Transient<\/code> bir varl\u0131\u011f\u0131 al\u0131r ve onu <code>Persistent<\/code> duruma ge\u00e7irir. Bu i\u015flem s\u0131ras\u0131nda, varl\u0131\u011fa bir kimlik (ID) de\u011feri atan\u0131r (e\u011fer ID veritaban\u0131 taraf\u0131ndan otomatik olarak \u00fcretiliyorsa).<br \/>\n*   <strong>ID \u00dcretimi:<\/strong> Varl\u0131\u011f\u0131n ID&#8217;si, veritaban\u0131 stratejisine (\u00f6rne\u011fin <code>AUTO<\/code>, <code>IDENTITY<\/code>, <code>SEQUENCE<\/code>) g\u00f6re olu\u015fturulur ve varl\u0131k nesnesine set edilir. <code>save()<\/code> metodu, atanan bu ID de\u011ferini <code>Serializable<\/code> t\u00fcr\u00fcnde d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <strong>Dirty Checking:<\/strong> Varl\u0131k <code>Persistent<\/code> duruma ge\u00e7ti\u011fi anda, <code>Session<\/code> taraf\u0131ndan y\u00f6netilmeye ba\u015flar. Bu noktadan sonra varl\u0131k \u00fczerinde yap\u0131lan de\u011fi\u015fiklikler, <code>Session<\/code>&#8216;\u0131n <code>flush<\/code> edilmesi veya <code>commit<\/code> edilmesi s\u0131ras\u0131nda otomatik olarak veritaban\u0131na yans\u0131t\u0131l\u0131r.<br \/>\n*   <strong>Detached Varl\u0131klarla Kullan\u0131m:<\/strong> <code>save()<\/code> metodu, <code>Detached<\/code> bir varl\u0131k \u00fczerinde \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda bir <code>NonUniqueObjectException<\/code> veya <code>PersistentObjectException<\/code> hatas\u0131 f\u0131rlat\u0131r, \u00e7\u00fcnk\u00fc <code>Detached<\/code> bir varl\u0131\u011f\u0131n zaten bir ID&#8217;si vard\u0131r ve <code>save()<\/code> metodu yeni bir kay\u0131t eklemeyi bekler.<br \/>\n*   <strong>Performans:<\/strong> <code>save()<\/code> metodu, <code>Session<\/code>&#8216;\u0131n \u00f6nbelle\u011fine (first-level cache) ekleme yapar ve genellikle hemen bir <code>INSERT<\/code> sorgusu \u00e7al\u0131\u015ft\u0131rmaz. Sorgu, <code>Session<\/code>&#8216;\u0131n <code>flush<\/code> edilmesi an\u0131nda \u00e7al\u0131\u015ft\u0131r\u0131l\u0131r.<\/p>\n<h4>\u00d6rnek Kullan\u0131m<\/h4>\n<p>\u00d6nce <code>User<\/code> entity s\u0131n\u0131f\u0131n\u0131 tan\u0131mlayal\u0131m:<\/p>\n<pre><code class=\"language-java\">\/\/ User.java\n@Entity\n@Table(name = \"users\")\npublic class User {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n    private String name;\n    private String email;\n\n    public User() {}\n\n    public User(String name, String email) {\n        this.name = name;\n        this.email = email;\n    }\n\n    \/\/ Getters and Setters\n    public Long getId() { return id; }\n    public void setId(Long id) { this.id = id; }\n    public String getName() { return name; }\n    public void setName(String name) { this.name = name; }\n    public String getEmail() { return email; }\n    public void setEmail(String email) { this.email = email; }\n\n    @Override\n    public String toString() {\n        return \"User{\" +\n               \"id=\" + id +\n               \", name='\" + name + '\\'' +\n               \", email='\" + email + '\\'' +\n               '}';\n    }\n}<\/code><\/pre>\n<p>\u015eimdi <code>save()<\/code> metodunu kullanal\u0131m:<\/p>\n<pre><code class=\"language-java\">\/\/ HibernateUtil s\u0131n\u0131f\u0131n\u0131z\u0131n oldu\u011funu varsayal\u0131m\nSession session = HibernateUtil.getSessionFactory().openSession();\nTransaction transaction = null;\n\ntry {\n    transaction = session.beginTransaction();\n\n    User newUser = new User(\"Charlie\", \"charlie@example.com\"); \/\/ Transient durumda\n    System.out.println(\"newUser (Transient): \" + newUser);\n    \n    Long userId = (Long) session.save(newUser); \/\/ newUser persistent duruma ge\u00e7ti\n    System.out.println(\"newUser (Persistent, after save): \" + newUser);\n    System.out.println(\"Generated ID: \" + userId);\n\n    newUser.setEmail(\"charlie_new@example.com\"); \/\/ Persistent nesne \u00fczerinde de\u011fi\u015fiklik\n    System.out.println(\"newUser (Persistent, after modification): \" + newUser);\n\n    transaction.commit(); \/\/ De\u011fi\u015fiklikler veritaban\u0131na yans\u0131r\n    System.out.println(\"User saved and committed.\");\n\n} catch (Exception e) {\n    if (transaction != null) {\n        transaction.rollback();\n    }\n    e.printStackTrace();\n} finally {\n    session.close();\n}<\/code><\/pre>\n<p>Yukar\u0131daki \u00f6rnekte, <code>newUser<\/code> nesnesi <code>save()<\/code> \u00e7a\u011fr\u0131lmadan \u00f6nce <code>Transient<\/code> durumdad\u0131r. <code>save()<\/code> \u00e7a\u011fr\u0131ld\u0131ktan sonra <code>Persistent<\/code> duruma ge\u00e7er ve bir ID al\u0131r. Bu noktadan sonra yap\u0131lan <code>setEmail<\/code> de\u011fi\u015fikli\u011fi, <code>commit()<\/code> \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda veritaban\u0131na yans\u0131t\u0131l\u0131r.<\/p>\n<h3><code>persist()<\/code> Metodu<\/h3>\n<p><code>persist()<\/code> metodu, <code>save()<\/code> metoduna benzer \u015fekilde <code>Transient<\/code> durumdaki bir varl\u0131\u011f\u0131 <code>Persistent<\/code> duruma ge\u00e7irmek i\u00e7in kullan\u0131l\u0131r. Ancak <code>persist()<\/code>, JPA spesifikasyonunun bir par\u00e7as\u0131d\u0131r ve <code>save()<\/code>&#8216;e g\u00f6re baz\u0131 \u00f6nemli farkl\u0131l\u0131klar\u0131 vard\u0131r.<\/p>\n<h4>Davran\u0131\u015f ve \u00d6zellikler<\/h4>\n<p>*   <strong>JPA Standart\u0131:<\/strong> <code>persist()<\/code> metodu, JPA&#8217;n\u0131n bir par\u00e7as\u0131d\u0131r. Bu, uygulaman\u0131z\u0131n Hibernate yerine ba\u015fka bir JPA implementasyonu (\u00f6rne\u011fin EclipseLink) kullanmas\u0131 durumunda da ayn\u0131 davran\u0131\u015f\u0131 sergileyece\u011fi anlam\u0131na gelir.<br \/>\n*   <strong>Void D\u00f6n\u00fc\u015f Tipi:<\/strong> <code>persist()<\/code> metodu <code>void<\/code> d\u00f6nd\u00fcr\u00fcr. Yani, <code>save()<\/code> metodunun aksine, varl\u0131\u011f\u0131n atanan ID&#8217;sini do\u011frudan d\u00f6nd\u00fcrmez. ID, varl\u0131k nesnesinin kendisine set edilir.<br \/>\n*   <strong>ID \u00dcretimi ve Garantisi:<\/strong> <code>persist()<\/code> metodu, <code>save()<\/code> gibi ID&#8217;yi \u00fcretir ve varl\u0131k nesnesine set eder. Ancak, <code>persist()<\/code> \u00e7a\u011fr\u0131ld\u0131ktan hemen sonra varl\u0131k nesnesinin ID&#8217;sinin garanti alt\u0131na al\u0131nd\u0131\u011f\u0131 s\u00f6ylenemez. \u00d6zellikle <code>IDENTITY<\/code> stratejisi kullan\u0131ld\u0131\u011f\u0131nda, ID&#8217;nin olu\u015fumu <code>flush<\/code> i\u015flemi an\u0131na kadar ertelenebilir. Bu durum, <code>persist()<\/code> \u00e7a\u011fr\u0131ld\u0131ktan hemen sonra varl\u0131\u011f\u0131n ID&#8217;sini kullanmaya \u00e7al\u0131\u015f\u0131rsan\u0131z sorunlara yol a\u00e7abilir. <code>save()<\/code> ise ID&#8217;yi hemen d\u00f6nd\u00fcrd\u00fc\u011f\u00fc i\u00e7in bu konuda daha kesindir.<br \/>\n*   <strong>Detached Varl\u0131klarla Kullan\u0131m:<\/strong> <code>persist()<\/code> metodu da <code>Detached<\/code> bir varl\u0131k \u00fczerinde \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda bir <code>EntityExistsException<\/code> veya benzeri bir hata f\u0131rlat\u0131r, \u00e7\u00fcnk\u00fc mevcut bir ID&#8217;ye sahip bir varl\u0131\u011f\u0131 &#8220;yeni&#8221; olarak kaydetmeye \u00e7al\u0131\u015f\u0131r.<br \/>\n*   <strong>Cascading:<\/strong> <code>persist()<\/code> metodu, ili\u015fkili varl\u0131klar \u00fczerinde <code>CascadeType.PERSIST<\/code> veya <code>CascadeType.ALL<\/code> tan\u0131mlanm\u0131\u015fsa, bu ili\u015fkili varl\u0131klar\u0131 da <code>Persistent<\/code> duruma ge\u00e7irir.<\/p>\n<h4>\u00d6rnek Kullan\u0131m<\/h4>\n<pre><code class=\"language-java\">Session session = HibernateUtil.getSessionFactory().openSession();\nTransaction transaction = null;\n\ntry {\n    transaction = session.beginTransaction();\n\n    User newUser = new User(\"David\", \"david@example.com\"); \/\/ Transient durumda\n    System.out.println(\"newUser (Transient): \" + newUser);\n    \n    session.persist(newUser); \/\/ newUser persistent duruma ge\u00e7ti\n    \/\/ ID'nin hemen atan\u0131p atanmad\u0131\u011f\u0131n\u0131 kontrol edelim\n    System.out.println(\"newUser (Persistent, after persist, ID may or may not be set yet): \" + newUser);\n\n    \/\/ E\u011fer ID hemen atanmad\u0131ysa ve ona ihtiyac\u0131n\u0131z varsa, session.flush() \u00e7a\u011f\u0131rabilirsiniz\n    \/\/ session.flush(); \n    \/\/ System.out.println(\"newUser (Persistent, after flush, ID is guaranteed): \" + newUser);\n\n    newUser.setEmail(\"david_new@example.com\"); \/\/ Persistent nesne \u00fczerinde de\u011fi\u015fiklik\n\n    transaction.commit(); \/\/ De\u011fi\u015fiklikler veritaban\u0131na yans\u0131r, ID de bu a\u015famada kesinle\u015fir\n    System.out.println(\"User persisted and committed.\");\n    System.out.println(\"newUser (Persistent, after commit): \" + newUser);\n\n} catch (Exception e) {\n    if (transaction != null) {\n        transaction.rollback();\n    }\n    e.printStackTrace();\n} finally {\n    session.close();\n}<\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>persist()<\/code> \u00e7a\u011fr\u0131ld\u0131ktan hemen sonra <code>newUser.getId()<\/code>&#8216;nin <code>null<\/code> olup olmad\u0131\u011f\u0131n\u0131 kontrol etmek \u00f6nemlidir. E\u011fer <code>IDENTITY<\/code> stratejisi kullan\u0131l\u0131yorsa, ID&#8217;nin <code>commit<\/code> veya <code>flush<\/code> an\u0131nda atanmas\u0131 daha olas\u0131d\u0131r.<\/p>\n<h3><code>update()<\/code> Metodu<\/h3>\n<p><code>update()<\/code> metodu, <code>Detached<\/code> durumdaki bir varl\u0131\u011f\u0131 tekrar <code>Persistent<\/code> duruma ge\u00e7irmek ve \u00fczerinde yap\u0131lan de\u011fi\u015fiklikleri veritaban\u0131na yans\u0131tmak i\u00e7in kullan\u0131l\u0131r. Bu metot da Hibernate&#8217;e \u00f6zg\u00fcd\u00fcr.<\/p>\n<h4>Davran\u0131\u015f ve \u00d6zellikler<\/h4>\n<p>*   <strong>Detached&#8217;tan Persistent&#8217;a:<\/strong> <code>update()<\/code> metodu, daha \u00f6nce bir <code>Session<\/code> taraf\u0131ndan y\u00f6netilmi\u015f, ancak art\u0131k <code>Detached<\/code> durumda olan bir varl\u0131\u011f\u0131 al\u0131r ve onu tekrar <code>Persistent<\/code> duruma getirir.<br \/>\n*   <strong>ID Varl\u0131\u011f\u0131:<\/strong> <code>update()<\/code> metodu, varl\u0131\u011f\u0131n ge\u00e7erli bir ID&#8217;ye sahip olmas\u0131n\u0131 bekler. E\u011fer varl\u0131\u011f\u0131n ID&#8217;si <code>null<\/code> ise veya ge\u00e7ersizse bir hata f\u0131rlatabilir.<br \/>\n<em>   <strong>Ayn\u0131 ID&#8217;ye Sahip Ba\u015fka Varl\u0131k:<\/strong> E\u011fer <code>Session<\/code>&#8216;\u0131n \u00f6nbelle\u011finde (first-level cache) <code>update()<\/code> edilmeye \u00e7al\u0131\u015f\u0131lan varl\u0131kla ayn\u0131 ID&#8217;ye sahip <\/em>farkl\u0131 bir varl\u0131k* zaten varsa, <code>update()<\/code> metodu bir <code>NonUniqueObjectException<\/code> f\u0131rlat\u0131r. Bu, <code>Session<\/code> i\u00e7inde ayn\u0131 ID&#8217;ye sahip iki farkl\u0131 varl\u0131k nesnesinin bulunmas\u0131n\u0131 engeller.<br \/>\n*   <strong>Transient Varl\u0131klarla Kullan\u0131m:<\/strong> <code>update()<\/code> metodu, <code>Transient<\/code> bir varl\u0131k \u00fczerinde \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda bir <code>PersistentObjectException<\/code> f\u0131rlat\u0131r, \u00e7\u00fcnk\u00fc <code>update()<\/code> varl\u0131\u011f\u0131n daha \u00f6nce veritaban\u0131nda var oldu\u011funu varsayar.<br \/>\n*   <strong>Void D\u00f6n\u00fc\u015f Tipi:<\/strong> <code>update()<\/code> metodu <code>void<\/code> d\u00f6nd\u00fcr\u00fcr. Orijinal <code>Detached<\/code> varl\u0131k nesnesi, <code>Persistent<\/code> duruma ge\u00e7er ve <code>Session<\/code> taraf\u0131ndan y\u00f6netilmeye ba\u015flar.<\/p>\n<h4>\u00d6rnek Kullan\u0131m<\/h4>\n<pre><code class=\"language-java\">Session session = HibernateUtil.getSessionFactory().openSession();\nTransaction transaction = null;\nUser detachedUser = null;\n\ntry {\n    transaction = session.beginTransaction();\n    \/\/ 1. Kullan\u0131c\u0131y\u0131 veritaban\u0131ndan \u00e7ek ve Detached duruma getir\n    User user = new User(\"Eve\", \"eve@example.com\");\n    session.save(user); \/\/ \u00d6nce kaydedelim ki ID'si olsun\n    transaction.commit();\n    session.close(); \/\/ Session'\u0131 kapatarak user'\u0131 Detached yapal\u0131m\n\n    detachedUser = user; \/\/ user art\u0131k detached durumda\n    System.out.println(\"detachedUser (Detached, initial): \" + detachedUser);\n\n    \/\/ 2. Detached kullan\u0131c\u0131 \u00fczerinde de\u011fi\u015fiklik yap\n    detachedUser.setEmail(\"new_eve@example.com\");\n    detachedUser.setName(\"Eve Smith\");\n    System.out.println(\"detachedUser (Detached, after modification): \" + detachedUser);\n\n    \/\/ 3. Yeni bir Session a\u00e7 ve detachedUser'\u0131 update et\n    session = HibernateUtil.getSessionFactory().openSession();\n    transaction = session.beginTransaction();\n    \n    session.update(detachedUser); \/\/ detachedUser persistent duruma ge\u00e7ti\n    System.out.println(\"detachedUser (Persistent, after update): \" + detachedUser);\n\n    transaction.commit(); \/\/ De\u011fi\u015fiklikler veritaban\u0131na yans\u0131r\n    System.out.println(\"User updated and committed.\");\n\n} catch (Exception e) {\n    if (transaction != null) {\n        transaction.rollback();\n    }\n    e.printStackTrace();\n} finally {\n    if (session != null && session.isOpen()) {\n        session.close();\n    }\n}<\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>detachedUser<\/code> \u00f6nce bir <code>Session<\/code> ile kaydedilir, ard\u0131ndan <code>Session<\/code> kapat\u0131larak <code>Detached<\/code> duruma getirilir. <code>Detached<\/code> durumdayken \u00fczerinde de\u011fi\u015fiklik yap\u0131l\u0131r ve yeni bir <code>Session<\/code> i\u00e7inde <code>update()<\/code> metodu kullan\u0131larak tekrar <code>Persistent<\/code> duruma ge\u00e7irilip de\u011fi\u015fiklikler veritaban\u0131na yans\u0131t\u0131l\u0131r.<\/p>\n<h3><code>merge()<\/code> Metodu<\/h3>\n<p><code>merge()<\/code> metodu, <code>Detached<\/code> bir varl\u0131\u011f\u0131 tekrar <code>Persistent<\/code> duruma getirmek veya <code>Transient<\/code> bir varl\u0131\u011f\u0131 <code>Persistent<\/code> duruma ge\u00e7irmek i\u00e7in kullan\u0131l\u0131r. <code>update()<\/code>&#8216;ten farkl\u0131 olarak, <code>merge()<\/code> metodu her zaman yeni bir <code>Persistent<\/code> varl\u0131k \u00f6rne\u011fi d\u00f6nd\u00fcr\u00fcr ve orijinal varl\u0131k nesnesinin durumunu de\u011fi\u015ftirmez. <code>merge()<\/code> metodu JPA spesifikasyonunun bir par\u00e7as\u0131d\u0131r.<\/p>\n<h4>Davran\u0131\u015f ve \u00d6zellikler<\/h4>\n<p>*   <strong>JPA Standart\u0131:<\/strong> <code>merge()<\/code> metodu, JPA&#8217;n\u0131n bir par\u00e7as\u0131d\u0131r.<br \/>\n*   <strong>D\u00f6n\u00fc\u015f Tipi (Yeni Persistent Varl\u0131k):<\/strong> <code>merge()<\/code> metodu, her zaman <code>Persistent<\/code> durumdaki bir varl\u0131k \u00f6rne\u011fi d\u00f6nd\u00fcr\u00fcr. Bu, <code>update()<\/code>&#8216;ten en \u00f6nemli fark\u0131d\u0131r. Orijinal varl\u0131k nesnesi (metoda parametre olarak verilen) <code>Detached<\/code> veya <code>Transient<\/code> durumunda kal\u0131r ve <code>Session<\/code> taraf\u0131ndan y\u00f6netilmez. <code>merge()<\/code>&#8216;den d\u00f6nen de\u011feri kullanmak esast\u0131r.<br \/>\n*   <strong>Detached Varl\u0131klarla Kullan\u0131m:<\/strong> E\u011fer metoda <code>Detached<\/code> bir varl\u0131k verilirse:<br \/>\n    *   <code>Session<\/code>&#8216;\u0131n \u00f6nbelle\u011finde ayn\u0131 ID&#8217;ye sahip bir <code>Persistent<\/code> varl\u0131k varsa, bu varl\u0131\u011f\u0131n durumu <code>Detached<\/code> varl\u0131\u011f\u0131n de\u011ferleriyle g\u00fcncellenir ve bu <code>Persistent<\/code> varl\u0131k d\u00f6nd\u00fcr\u00fcl\u00fcr.<br \/>\n    *   <code>Session<\/code>&#8216;\u0131n \u00f6nbelle\u011finde ayn\u0131 ID&#8217;ye sahip bir <code>Persistent<\/code> varl\u0131k yoksa, veritaban\u0131ndan bu ID&#8217;ye sahip varl\u0131k y\u00fcklenir, durumu <code>Detached<\/code> varl\u0131\u011f\u0131n de\u011ferleriyle g\u00fcncellenir ve bu y\u00fcklenen <code>Persistent<\/code> varl\u0131k d\u00f6nd\u00fcr\u00fcl\u00fcr.<br \/>\n*   <strong>Transient Varl\u0131klarla Kullan\u0131m:<\/strong> E\u011fer metoda <code>Transient<\/code> bir varl\u0131k verilirse (ID&#8217;si <code>null<\/code> veya varsay\u0131lan de\u011ferdeyse):<br \/>\n    *   <code>merge()<\/code> metodu, bu <code>Transient<\/code> varl\u0131\u011f\u0131 yeni bir <code>Persistent<\/code> varl\u0131k olarak kaydeder (t\u0131pk\u0131 <code>persist()<\/code> gibi).<br \/>\n    *   Yeni olu\u015fturulan <code>Persistent<\/code> varl\u0131k d\u00f6nd\u00fcr\u00fcl\u00fcr. Orijinal <code>Transient<\/code> varl\u0131k nesnesi <code>Transient<\/code> durumda kal\u0131r.<br \/>\n*   <strong>Persistent Varl\u0131klarla Kullan\u0131m:<\/strong> E\u011fer metoda <code>Persistent<\/code> bir varl\u0131k verilirse, <code>merge()<\/code> metodu basit\u00e7e bu varl\u0131\u011f\u0131 d\u00f6nd\u00fcr\u00fcr. Herhangi bir i\u015flem yapmaz.<br \/>\n*   <strong>Esneklik:<\/strong> <code>merge()<\/code> metodu, varl\u0131\u011f\u0131n <code>Transient<\/code> mi yoksa <code>Detached<\/code> m\u0131 oldu\u011fundan emin olmad\u0131\u011f\u0131n\u0131z durumlarda g\u00fcvenli bir se\u00e7enektir. Her iki durumda da do\u011fru i\u015flemi yapar ve her zaman <code>Persistent<\/code> bir varl\u0131k d\u00f6nd\u00fcr\u00fcr.<\/p>\n<h4>\u00d6rnek Kullan\u0131m<\/h4>\n<pre><code class=\"language-java\">Session session = HibernateUtil.getSessionFactory().openSession();\nTransaction transaction = null;\nUser originalDetachedUser = null;\nUser mergedUser = null;\n\ntry {\n    transaction = session.beginTransaction();\n    \/\/ 1. Kullan\u0131c\u0131y\u0131 veritaban\u0131ndan \u00e7ek ve Detached duruma getir\n    User user = new User(\"Frank\", \"frank@example.com\");\n    session.save(user); \/\/ \u00d6nce kaydedelim ki ID'si olsun\n    transaction.commit();\n    session.close(); \/\/ Session'\u0131 kapatarak user'\u0131 Detached yapal\u0131m\n\n    originalDetachedUser = user; \/\/ user art\u0131k detached durumda\n    System.out.println(\"originalDetachedUser (Detached, initial): \" + originalDetachedUser);\n\n    \/\/ 2. Detached kullan\u0131c\u0131 \u00fczerinde de\u011fi\u015fiklik yap\n    originalDetachedUser.setEmail(\"new_frank@example.com\");\n    originalDetachedUser.setName(\"Frank White\");\n    System.out.println(\"originalDetachedUser (Detached, after modification): \" + originalDetachedUser);\n\n    \/\/ 3. Yeni bir Session a\u00e7 ve detachedUser'\u0131 merge et\n    session = HibernateUtil.getSessionFactory().openSession();\n    transaction = session.beginTransaction();\n    \n    mergedUser = (User) session.merge(originalDetachedUser); \/\/ mergedUser persistent duruma ge\u00e7ti\n    \n    System.out.println(\"originalDetachedUser (Still Detached): \" + originalDetachedUser);\n    System.out.println(\"mergedUser (Persistent): \" + mergedUser);\n\n    \/\/ mergedUser \u00fczerinde yap\u0131lan de\u011fi\u015fiklikler veritaban\u0131na yans\u0131r\n    mergedUser.setEmail(\"final_frank@example.com\"); \n\n    transaction.commit(); \/\/ De\u011fi\u015fiklikler veritaban\u0131na yans\u0131r\n    System.out.println(\"User merged and committed.\");\n\n} catch (Exception e) {\n    if (transaction != null) {\n        transaction.rollback();\n    }\n    e.printStackTrace();\n} finally {\n    if (session != null && session.isOpen()) {\n        session.close();\n    }\n}\n\n\/\/ Transient bir varl\u0131kla merge kullan\u0131m\u0131\nSystem.out.println(\"\\n--- Transient Varl\u0131k ile merge ---\");\nsession = HibernateUtil.getSessionFactory().openSession();\ntransaction = null;\n\ntry {\n    transaction = session.beginTransaction();\n    User transientUser = new User(\"Grace\", \"grace@example.com\"); \/\/ Transient\n    System.out.println(\"transientUser (Transient): \" + transientUser);\n\n    User persistentUserFromMerge = (User) session.merge(transientUser);\n    \n    System.out.println(\"transientUser (Still Transient): \" + transientUser); \/\/ Orijinal transient kal\u0131r\n    System.out.println(\"persistentUserFromMerge (Persistent): \" + persistentUserFromMerge); \/\/ Yeni persistent nesne d\u00f6ner\n\n    persistentUserFromMerge.setEmail(\"new_grace@example.com\"); \/\/ Bu nesne \u00fczerinde yap\u0131lan de\u011fi\u015fiklikler izlenir\n\n    transaction.commit();\n    System.out.println(\"Transient user merged (saved) and committed.\");\n\n} catch (Exception e) {\n    if (transaction != null) {\n        transaction.rollback();\n    }\n    e.printStackTrace();\n} finally {\n    if (session != null && session.isOpen()) {\n        session.close();\n    }\n}<\/code><\/pre>\n<p><code>merge()<\/code> \u00f6rne\u011finde, <code>originalDetachedUser<\/code> nesnesi <code>merge()<\/code> \u00e7a\u011fr\u0131s\u0131ndan sonra hala <code>Detached<\/code> durumdad\u0131r. <code>Session<\/code> taraf\u0131ndan y\u00f6netilen ve veritaban\u0131na yans\u0131t\u0131lacak olan de\u011fi\u015fiklikler, <code>merge()<\/code> metodunun d\u00f6nd\u00fcrd\u00fc\u011f\u00fc <code>mergedUser<\/code> nesnesi \u00fczerinde yap\u0131lmal\u0131d\u0131r. <code>Transient<\/code> bir varl\u0131k ile kullan\u0131ld\u0131\u011f\u0131nda da benzer \u015fekilde, <code>merge<\/code> metodu yeni bir <code>Persistent<\/code> varl\u0131k d\u00f6nd\u00fcr\u00fcr ve orijinal <code>Transient<\/code> varl\u0131k de\u011fi\u015fmeden kal\u0131r.<\/p>\n<h3><code>saveOrUpdate()<\/code> Metodu<\/h3>\n<p><code>saveOrUpdate()<\/code> metodu, bir varl\u0131\u011f\u0131n <code>Transient<\/code> mi yoksa <code>Detached<\/code> m\u0131 oldu\u011funu otomatik olarak belirleyerek uygun i\u015flemi (kaydetme veya g\u00fcncelleme) ger\u00e7ekle\u015ftiren bir Hibernate kolayl\u0131k metodudur.<\/p>\n<h4>Davran\u0131\u015f ve \u00d6zellikler<\/h4>\n<p>*   <strong>Otomatik Karar Verme:<\/strong> <code>saveOrUpdate()<\/code> metodu, varl\u0131\u011f\u0131n ID&#8217;sine ve <code>@Version<\/code> (e\u011fer kullan\u0131l\u0131yorsa) alan\u0131na bakarak varl\u0131\u011f\u0131n yeni mi (<code>Transient<\/code>) yoksa mevcut bir kayd\u0131n ayr\u0131k hali mi (<code>Detached<\/code>) oldu\u011funa karar verir.<br \/>\n    *   E\u011fer varl\u0131\u011f\u0131n ID&#8217;si <code>null<\/code> ise veya <code>unsaved-value<\/code> olarak belirtilen de\u011fere e\u015fitse (varsay\u0131lan olarak 0 veya <code>null<\/code>), varl\u0131\u011f\u0131 <code>Transient<\/code> kabul eder ve <code>save()<\/code> gibi davran\u0131r.<br \/>\n    *   E\u011fer varl\u0131\u011f\u0131n ge\u00e7erli bir ID&#8217;si varsa ve <code>@Version<\/code> alan\u0131 varsa ve varsay\u0131lan de\u011feri a\u015fm\u0131\u015fsa, varl\u0131\u011f\u0131 <code>Detached<\/code> kabul eder ve <code>update()<\/code> gibi davran\u0131r.<br \/>\n*   <strong>Void D\u00f6n\u00fc\u015f Tipi:<\/strong> <code>saveOrUpdate()<\/code> metodu <code>void<\/code> d\u00f6nd\u00fcr\u00fcr. Metoda verilen orijinal varl\u0131k nesnesi, <code>Persistent<\/code> duruma ge\u00e7er.<br \/>\n*   <strong>Esneklik ve Potansiyel Risk:<\/strong> Bu metot, varl\u0131\u011f\u0131n durumunu bilmedi\u011finiz veya kodunuzu basitle\u015ftirmek istedi\u011finiz durumlarda kullan\u0131\u015fl\u0131 olabilir. Ancak, otomatik karar verme mekanizmas\u0131 bazen beklenmedik davran\u0131\u015flara yol a\u00e7abilir, \u00f6zellikle ID&#8217;lerin manuel olarak atanmas\u0131 veya karma\u015f\u0131k varl\u0131k modelleri s\u00f6z konusu oldu\u011funda.<br \/>\n*   <strong>JPA Kar\u015f\u0131l\u0131\u011f\u0131 Yok:<\/strong> <code>saveOrUpdate()<\/code> metodu Hibernate&#8217;e \u00f6zg\u00fcd\u00fcr ve JPA&#8217;da do\u011frudan bir kar\u015f\u0131l\u0131\u011f\u0131 yoktur.<\/p>\n<h4>\u00d6rnek Kullan\u0131m<\/h4>\n<pre><code class=\"language-java\">Session session = HibernateUtil.getSessionFactory().openSession();\nTransaction transaction = null;\n\ntry {\n    transaction = session.beginTransaction();\n\n    \/\/ 1. Transient bir varl\u0131k i\u00e7in saveOrUpdate (save gibi davran\u0131r)\n    User transientUser = new User(\"Henry\", \"henry@example.com\"); \/\/ Transient\n    System.out.println(\"transientUser (Transient, before saveOrUpdate): \" + transientUser);\n    \n    session.saveOrUpdate(transientUser);\n    System.out.println(\"transientUser (Persistent, after saveOrUpdate): \" + transientUser); \/\/ ID atanm\u0131\u015f olmal\u0131\n\n    \/\/ 2. Detached bir varl\u0131k i\u00e7in saveOrUpdate (update gibi davran\u0131r)\n    transaction.commit(); \/\/ Henry'yi kaydet\n    session.close(); \/\/ Session'\u0131 kapat, transientUser art\u0131k detached\n\n    User detachedUser = transientUser; \/\/ detachedUser art\u0131k detached durumda\n    System.out.println(\"detachedUser (Detached, initial): \" + detachedUser);\n    detachedUser.setEmail(\"new_henry@example.com\"); \/\/ De\u011fi\u015fiklik yap\n\n    session = HibernateUtil.getSessionFactory().openSession();\n    transaction = session.beginTransaction();\n\n    session.saveOrUpdate(detachedUser); \/\/ detachedUser persistent duruma ge\u00e7ti\n    System.out.println(\"detachedUser (Persistent, after saveOrUpdate): \" + detachedUser);\n\n    transaction.commit(); \/\/ De\u011fi\u015fiklikler veritaban\u0131na yans\u0131r\n    System.out.println(\"User (Henry) saved, updated and committed using saveOrUpdate.\");\n\n} catch (Exception e) {\n    if (transaction != null) {\n        transaction.rollback();\n    }\n    e.printStackTrace();\n} finally {\n    if (session != null && session.isOpen()) {\n        session.close();\n    }\n}<\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>saveOrUpdate()<\/code> metodu \u00f6nce <code>Transient<\/code> bir varl\u0131\u011f\u0131 kaydetmek i\u00e7in, ard\u0131ndan <code>Detached<\/code> bir varl\u0131\u011f\u0131 g\u00fcncellemek i\u00e7in kullan\u0131lm\u0131\u015ft\u0131r. Her iki durumda da do\u011fru i\u015flemi otomatik olarak belirleyip ger\u00e7ekle\u015ftirir.<\/p>\n<h3>Metotlar\u0131n Kar\u015f\u0131la\u015ft\u0131rmas\u0131 ve Ne Zaman Hangisini Kullanmal\u0131?<\/h3>\n<p>A\u015fa\u011f\u0131daki tablo, incelenen metotlar\u0131n temel \u00f6zelliklerini \u00f6zetlemektedir:<\/p>\n<p>| Metot          | JPA Standard\u0131 m\u0131? | Giri\u015f Varl\u0131\u011f\u0131 Durumu | D\u00f6n\u00fc\u015f De\u011feri                  | Orijinal Varl\u0131k Durumu De\u011fi\u015fir mi? | Ana Ama\u00e7                                 | Notlar                                                                                                                                                                             |<br \/>\n| :&#8212;&#8212;&#8212;&#8212;- | :&#8212;&#8212;&#8212;&#8212;&#8212;- | :&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- | :&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- | :&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; | :&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- | :&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; |<br \/>\n| <code>save()<\/code>       | Hay\u0131r (Hibernate) | Transient            | <code>Serializable<\/code> (ID)           | Evet (Persistent olur)             | Yeni varl\u0131\u011f\u0131 kaydetme                     | Detached varl\u0131klarla hata verir. ID&#8217;yi hemen d\u00f6nd\u00fcr\u00fcr.                                                                                                                               |<br \/>\n| <code>persist()<\/code>    | Evet (JPA)        | Transient            | <code>void<\/code>                        | Evet (Persistent olur)             | Yeni varl\u0131\u011f\u0131 kaydetme                     | Detached varl\u0131klarla hata verir. ID&#8217;nin hemen atanaca\u011f\u0131n\u0131 garanti etmez (flush\/commit&#8217;e kadar ertelenebilir). Tercih edilen yeni kay\u0131t metodu.                                      |<br \/>\n| <code>update()<\/code>     | Hay\u0131r (Hibernate) | Detached             | <code>void<\/code>                        | Evet (Persistent olur)             | Detached varl\u0131\u011f\u0131 tekrar ba\u011flama\/g\u00fcncelleme | Transient varl\u0131klarla hata verir. Ayn\u0131 ID&#8217;ye sahip ba\u015fka bir Persistent nesne varsa hata verir. Orijinal nesneyi persistent yapar.                                                 |<br \/>\n| <code>merge()<\/code>      | Evet (JPA)        | Transient, Detached, Persistent | <code>Persistent<\/code> varl\u0131k \u00f6rne\u011fi | Hay\u0131r (Orijinal ayn\u0131 kal\u0131r)        | Varl\u0131\u011f\u0131 Persistent yapma veya g\u00fcncelleme | Her zaman yeni veya mevcut bir Persistent nesne d\u00f6nd\u00fcr\u00fcr. Orijinal nesne Detached\/Transient kal\u0131r. En esnek ve g\u00fcvenli metotlardan biri.                                        |<br \/>\n| <code>saveOrUpdate()<\/code> | Hay\u0131r (Hibernate) | Transient, Detached  | <code>void<\/code>                        | Evet (Persistent olur)             | Varl\u0131\u011f\u0131n durumuna g\u00f6re kaydet\/g\u00fcncelle | Hibernate&#8217;e \u00f6zg\u00fc bir kolayl\u0131k metodudur. Durumu otomatik belirler. Baz\u0131 durumlarda beklenmedik davran\u0131\u015flara yol a\u00e7abilir.                                                              |<\/p>\n<h4>Ne Zaman Hangisini Kullanmal\u0131?<\/h4>\n<p>*   <strong>Yeni Varl\u0131k Kaydetme:<\/strong><br \/>\n    *   <strong><code>persist()<\/code>:<\/strong> Yeni bir varl\u0131\u011f\u0131 veritaban\u0131na kaydetmek i\u00e7in tercih edilen JPA standard\u0131 y\u00f6ntemidir. Temiz ve standart bir yakla\u015f\u0131md\u0131r. ID&#8217;ye hemen ihtiyac\u0131n\u0131z yoksa kullan\u0131n.<br \/>\n    *   <strong><code>save()<\/code>:<\/strong> <code>persist()<\/code>&#8216;e alternatif olarak kullan\u0131labilir, ancak <code>persist()<\/code> tercih edilmelidir. <code>save()<\/code> ID&#8217;yi hemen d\u00f6nd\u00fcrme garantisi verir.<br \/>\n*   <strong>Detached Varl\u0131\u011f\u0131 G\u00fcncelleme\/Tekrar Ba\u011flama:<\/strong><br \/>\n    *   <strong><code>merge()<\/code>:<\/strong> En g\u00fcvenli ve esnek se\u00e7enektir. Varl\u0131\u011f\u0131n <code>Detached<\/code> m\u0131 yoksa <code>Transient<\/code> m\u0131 oldu\u011fundan emin olmad\u0131\u011f\u0131n\u0131zda veya orijinal nesnenin <code>Detached<\/code> kalmas\u0131n\u0131 tercih etti\u011finizde kullan\u0131n. Her zaman <code>Persistent<\/code> bir kopya d\u00f6nd\u00fcrd\u00fc\u011f\u00fc i\u00e7in bu kopyay\u0131 kullanmay\u0131 unutmay\u0131n.<br \/>\n    *   <strong><code>update()<\/code>:<\/strong> E\u011fer kesinlikle <code>Detached<\/code> bir varl\u0131\u011f\u0131 tekrar <code>Persistent<\/code> duruma getirmek ve orijinal nesnenin kendisini <code>Persistent<\/code> yapmak istiyorsan\u0131z kullan\u0131n. <code>Session<\/code> i\u00e7inde ayn\u0131 ID&#8217;ye sahip ba\u015fka bir nesne olmad\u0131\u011f\u0131ndan emin olmal\u0131s\u0131n\u0131z.<br \/>\n*   <strong>Hem Yeni Kaydetme Hem de G\u00fcncelleme (Otomatik):<\/strong><br \/>\n    *   <strong><code>saveOrUpdate()<\/code>:<\/strong> Yaln\u0131zca Hibernate kullan\u0131yorsan\u0131z ve varl\u0131\u011f\u0131n <code>Transient<\/code> mi yoksa <code>Detached<\/code> mi oldu\u011funu manuel olarak kontrol etmek istemiyorsan\u0131z bir kolayl\u0131k olarak kullan\u0131labilir. Ancak, genellikle <code>persist()<\/code> ve <code>merge()<\/code>&#8216;i a\u00e7\u0131k\u00e7a kullanmak daha anla\u015f\u0131l\u0131r ve daha az hata potansiyeli ta\u015f\u0131r.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Hibernate&#8217;in <code>save<\/code>, <code>persist<\/code>, <code>update<\/code>, <code>merge<\/code> ve <code>saveOrUpdate<\/code> metotlar\u0131, varl\u0131klar\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fcn\u00fc y\u00f6netmede merkezi bir rol oynar. Her bir metot, varl\u0131\u011f\u0131n mevcut durumuna (Transient, Persistent, Detached) g\u00f6re farkl\u0131 davran\u0131\u015flar sergiler ve belirli senaryolar i\u00e7in en uygun olan\u0131 vard\u0131r.<\/p>\n<p><code>persist()<\/code> ve <code>merge()<\/code> metotlar\u0131 JPA standard\u0131n\u0131n bir par\u00e7as\u0131 oldu\u011fu i\u00e7in, ta\u015f\u0131nabilir uygulamalar geli\u015ftirmek isteyen geli\u015ftiriciler taraf\u0131ndan tercih edilmelidir. <code>persist()<\/code> yeni varl\u0131klar\u0131 kaydetmek i\u00e7in, <code>merge()<\/code> ise hem yeni varl\u0131klar\u0131 kaydetmek hem de ayr\u0131k varl\u0131klar\u0131 g\u00fcncellemek i\u00e7in esnek ve g\u00fcvenli bir yol sunar. <code>save()<\/code> ve <code>update()<\/code> Hibernate&#8217;e \u00f6zg\u00fc metotlard\u0131r ve <code>saveOrUpdate()<\/code> de bir kolayl\u0131k metodudur.<\/p>\n<p>Bu metotlar\u0131n inceliklerini ve aralar\u0131ndaki farklar\u0131 anlamak, Hibernate uygulamalar\u0131nda veri tutarl\u0131l\u0131\u011f\u0131n\u0131 sa\u011flamak, beklenmedik hatalar\u0131 \u00f6nlemek ve performans\u0131 optimize etmek i\u00e7in kritik \u00f6neme sahiptir. Do\u011fru metodu do\u011fru zamanda kullanmak, sa\u011flam ve bak\u0131m\u0131 kolay bir ORM katman\u0131 olu\u015fturman\u0131n temelidir.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme\nGiri\u015f: Hibernate ve Varl\u0131k Y\u00f6netimi\nModern Java uy","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-35976","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 Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme - 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\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme\" \/>\n<meta property=\"og:description\" content=\"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme Giri\u015f: Hibernate ve Varl\u0131k Y\u00f6netimi Modern Java uy\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-06T06:40:44+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=\"19 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme\",\"datePublished\":\"2025-12-06T06:40:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/\"},\"wordCount\":2564,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/\",\"name\":\"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-06T06:40:44+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme\"}]},{\"@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 Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme - 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\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/","og_locale":"tr_TR","og_type":"article","og_title":"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme","og_description":"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme Giri\u015f: Hibernate ve Varl\u0131k Y\u00f6netimi Modern Java uy","og_url":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-06T06:40:44+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"19 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme","datePublished":"2025-12-06T06:40:44+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/"},"wordCount":2564,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/","url":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/","name":"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-06T06:40:44+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/hibernate-session-merge-update-save-saveorupdate-persist-metotlari-detayli-bir-inceleme\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Hibernate Session merge, update, save, saveOrUpdate, persist Metotlar\u0131: Detayl\u0131 Bir \u0130nceleme"}]},{"@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\/35976","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=35976"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35976\/revisions"}],"predecessor-version":[{"id":35977,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35976\/revisions\/35977"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=35976"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=35976"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=35976"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}