1 Haziran 2014 Pazar

Hibernate'de Sık Rastlanan Hatalar ve Çözümleri

Merhaba arkadaşlar,

Bugüne kadar sizlere Hibernate teknolojisinin temel özelliklerinden bahsetmeye çalıştım. Bugün de Hibernate kullanırken sıkca karşılaştığımız hatalardan  ve bu hataların çözümlerinden bahsedeceğim.

1- Veritabanımızda kolon adı olarak kullandığımız kelimenin anahtar kelime (keyword) olmasından dolayı kaynaklanan hata ve çözümü

Örneğin veritabanı aracımız olan MySQL'de bir tablo oluşturduk ve bu tablonun kolonlarından birisinin adını 'DESC' olarak belirledik ve aşağıdaki gibi kolon adı ve veri tipini oluşturduk.

`DESC` VARCHAR(255) NOT NULL,

Belirlediğimiz bu kolonumuzu java sınıflarıyla eşlemeyi XML Mapping ya da Hibernate Anotasyonları kullanarak gerçekleştirdik.

XML Mapping ile eşleme 
Daha önceki konulardan da hatırlayacağınız üzere veritabanında oluşturduğumuz tablomuzun bilgilerini XML mapping dosyamıza yazıyorduk.

<hibernate-mapping>
    <class name="com.example.hibernate.Sirket" table="Sirket" >
        ...
        <property name="desc" type="string">
            <column name="DESC" not-null="true" />
        </property>
       ...
    </class>
</hibernate-mapping>

Anotasyon kullanarak eşleme 
Mapping işlemimizi gerçekleştirirken ikinci bir yöntem olarak Hibernate Anotasyonları'nı kullanıyorduk.

@Column(name = "DESC", nullable = false)
 public String getDesc() {
        return this.desc;
 }

Yukarıda bahsettiğimiz iki yöntemden birini kullanarak eşleme işlemini gerçekleştirdikten sonra tablomuza yeni bir veri eklemek istediğimizde aşağıdaki gibi bir hata ile karşılaşırız:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:

Bu hata bize MySQL'de tablo oluştururken yazım hatası yaptığımızı söyler. Aslında bu hata tablomuzun kolonunu oluştururken anahtar kelime kullandığımız için meydana gelmiştir. Bu hatayı düzeltmek için kolon adı olarak kullandığımız ve aslında anahtar kelime olan 'DESC' kelimesini köşeli parantez içine alarak [DESC] şeklinde yazmamız gerekiyor. Yaptığımız bu değişikliği XML mapping dosyamıza ve Hibernate Anotasyon'umuza uyarlıyoruz ve son halinin aşağıdaki gibi olmasını sağlıyoruz.

XML mapping
<hibernate-mapping>
    <class name="com.example.hibernate.Sirket" table="Sirket" >
        ...
        <property name="desc" type="string">
            <column name="[DESC]" not-null="true" />
        </property>
       ...
    </class>
</hibernate-mapping>

Hibernate Anotasyon
@Column(name = "[DESC]", nullable = false)
 public String getDesc() {
        return this.desc;
 }

2-  AnnotationConfiguration sınıfının kullanılması

Hibernate 3.6 versiyonundan önceki versiyonlarda AnnotationConfiguration sınıfı kullanılıyordu fakat 3.6 sürümü ile AnnotationConfiguration sınıfı yerini Configuration sınıfına bıraktı.

Hibernate 3.6 versiyonu öncesi
import org.hibernate.cfg.AnnotationConfiguration;
//...
private static SessionFactory buildSessionFactory() {
            try {

                        return new AnnotationConfiguration().configure().buildSessionFactory();

            } catch (Throwable ex) {

                        System.err.println("SessionFactory oluşturulurken hata meydana geldi." + ex);
                        throw new ExceptionInInitializerError(ex);
            }
}

Hibernate 3.6 versiyonu ve sonrası
import org.hibernate.cfg.Configuration;
//...
private static SessionFactory buildSessionFactory() {
            try {

                        return new Configuration().configure().buildSessionFactory();

            } catch (Throwable ex) {

                        System.err.println("SessionFactory oluşturulurken hata meydana geldi." + ex);
                        throw new ExceptionInInitializerError(ex);
            }

}

3-Java.Lang.ClassNotFoundException:Javax.Persistence.Entity hatası

Bu hata Entity sınıfının projemize dahil edilmediğinden kaynaklanır. Eğer projelerimizde bu hatayı alıyorsa J2EE SDK kütüphanesi olan javaee.jar dosyasını projemizin classpath'ine koymayı unutmuşuz demektir. Bu kütüphaneyi projemize dahil ederek hatayı gidermiş oluruz.
javaee.jar dosyasını buradan indirebilirsiniz.

4- AnnotationException: Unknown Id.Generator hatası


Eğer veritabanı olarak PostgreSQL kullanıyorsanız ve tablonun Id değerinin anotasyon kullanarak eşlemek istiyorsanız @SequenceGenerator anotasyonunu kullanmanız gerekiyor. Eğer bu anotasyonu kullanmayıp eşleme işlemini aşağıdaki gibi gerçekleştirirsek;


@Id
@Column(name="user_id", nullable=false)     
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="account_user_id_seq")
    private int userId;

şu hata ile karşılaşırız:

org.hibernate.AnnotationException: Unknown Id.generator

Yukarıdaki Id eşleme işlemini gerçekleştirirken @SequenceGenerator anotasyonunu kullanırsak yukarıdaki hata ile karşılaşmayız.

@Id      
@Column(name="user_id", nullable=false)     
@SequenceGenerator(name="my_seq", sequenceName="account_user_id_seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE ,generator="my_seq")
    private int userId;

Bu yazımda sizlere Hibernate'de en çok rastlanan hatalardan ve bu hataların çözümlerinden bahsettim.
Bu yazımla birlikte Hibernate yazı dizisine son veriyorum. Umarım birlikte geçirdiğimiz bu on haftalık süreç faydalı olmuştur. Görüşmek üzere şimdilik hoşçakalın.


25 Mayıs 2014 Pazar

Hibernate Inheritance One Table Per Hierarchy (Hibernate Anotasyon ile)

Merhaba arkadaşlar,

Bir önceki yazımızda Hibernate teknolojisinde Inheritance konusuna değinmiş ve 3 farklı Inheritance durumundan bahsetmiştik. Bunlardan ilki olan Table Per Subclass konusunu bir önceki yazımda işlemiştik.
Bu hafta ise bir başka Inheritance durumu olan Table Per Hierarchy konusuna değineceğiz.

Table Per Hierachy, birden fazla tabloyu tek bir tablo olarak tutmamızı sağlıyor. Peki bu durum bizlere ne gibi avantajlar sağlıyor? Derinlemesine hiyerarşisi olan yani sayıca çok tablosu olan ve bu tabloları hiyerarşik olarak tek tabloda tutan bir veritabanında bir "Select" sorgusu ile o veriye daha kolay ve daha hızlı bir şekilde ulaşmamızı sağlar.

Şimdi bu yapıyı daha iyi anlamamız için örnek bir proje oluşturalım.
Çalışan ve Kişi adında iki tabloyu tek bir tabloda birleştirelim ve Kisi adında tek bir tablo oluşturalım.
Bu tabloya Çalışan ve Kişi tablolarının attribute değerlerini yazalım. Tablonun primary keyini belirleyelim ve son olarak bu tabloları ayırt etmemizi sağlayacak discriminator adında bir kolon ekleyelim.


Daha sonra java kısmına geçelim ve sınıflarımızı oluşturalım.

İlk olarak Kisi.java sınıfımızı oluşturalım.

Hibernate anotasyonlarını kullanarak tablomuzu, java sınıfımızla eşliyoruz. @Entity ve @Table anotasyonu ile veritabanında bulunan tablomuzu eşliyoruz. Bunlara ek olarak  @Inheritance anotasyonu ile inheritance durumunu belirtiyoruz. Bu örnekte tabloları tek bir tabloda birleştirdiğimiz için Inheritance tipimizi SINGLE_TABLE olarak belirttik. Tablolarımızı ayırt etmemiz için oluşturduğumuz discriminator adlı kolonumuzu @DiscriminatorColumn anotasyonunu ile belirtiyoruz. Ayırıcı olarak tabloların baş harfini kullandığımız için discriminator tipi olarak String yazıyoruz. Tablolarımızın baş harflerini ayırıcı olarak belirtmek içinse @DiscriminatorValue anotasyonunu kullanıyoruz. Daha sonra @Column anotasyonu ile veritabanımızda bulunan attributelerden Kişi adlı tablomuzun attribute değerlerine karşılık gelen kolonları belirliyoruz.

İkinci tablomuz olan Çalışan tablomuzun java sınıfını oluşturalım.
Calisan.java

Bu sınıfımız için de @Entity ve @Table anotasyonlarını kullanıyoruz ve table adı olarak tek tablomuz olan kisi tablomuzun adını veriyoruz. Bu tablomuzu ayırt etmemiz discriminator değerini @DiscriminatorValue anotasyonu ile belirliyoruz ve tablomuzun baş harfini değer olarak veriyoruz. Daha sonra Calisan tablomuza ait olan kolonlarımızı eşlemek için @Column anotasyonunu kullanıyoruz.

Daha sonra bu sınıflarımızın birer mapping class olduğunu hibernate.cfg.xml dosyamıza belirtiyoruz.


Tablolarımıza karşılık gelen sınıflarımızı oluşturduktan sonra üzerinde işlem yapacağımız Main.java sınıfımızı oluşturalım.

Main sınıfımızda, HibernateUtil sınıfımızdan bir session oluşturduk ve transaction başlattık. Daha sonra Kisi ve Calisan sınıflarımızdan birer obje oluşturduk ve session'a kaydettik. Son olarak değişikliklerin veritabanına yansıması için transaction'ı commit ettik.
Projemizi çalıştıralım ve veritabanımızdaki değişikliği gözlemleyelim.
Console ekranımızda yukarıdaki gibi bir görünüm oluşacaktır ve veritabanımıza aşağıdaki kayıtlar eklenecektir.
Böylece projemizi sonladırdık. Umarım bu yazım Hibernate Inheritance One Table Per Hierarchy konusunu daha iyi anlamanıza yardımcı olmuştur. Bir sonraki yazımda görüşmek üzere. Hoşçakalın.

11 Mayıs 2014 Pazar

Hibernate Inheritance One Table Per Subclass (Hibernate Anotasyon ile)

Merhaba arkadaşlar,

Bu yazımda Hibernate teknolojisinde Inheritance konusuna değineceğim. Hibernate bizlere Inheritance(Kalıtım) konusunda 3 farklı yaklaşım sunuyor:

  • Table Per Subclass
  • Table Per Class Hierarchy
  • Table Per Concrete Class 
Bu yaklaşımlardan ilki olan Table Per Subclass konusuna değineceğiz ve bu konuyla ilgili bir uygulama yapacağız. Inheritance(Kalıtım) kavramını programlama yönünden açıklayacak olursak; süper yani ana sınıf ve ondan türeyen subclass yani alt sınıf veya sınıflar diye bahsedebiliriz. Peki bu inheritance Hibernate teknolojisinde nasıl oluyor? Hibernate'de bu zamana kadar hep veritabanı tablolarıyla uğraştığımızdan bu tablolar üzerinden inheritance durumunu inceleyeceğiz.
Table Per Subclass durumu için veritabanında bulunan bir tablo süper classa denk gelir, diğer tablolar da bu süper classtan türeyen alt sınıflara denk gelir. Alt sınıflar süper sınıfın primary keyi ile süper sınıfa bağlıdır. Şimdi bu durumu örnekleyen uygulamamıza geçelim.

Öncelikle veritabanı tablolarımızı oluşturarak  işe başlayalım. Bu uygulama için Araç, Otobüs ve Kamyon adında üç tablo oluşturacağız. Bu tablolardan Otobüs ve Kamyon tabloları Araç tablosuna kalıtım yoluyla bağlı olacaktır. 

Sırasıyla Araç, Otobüs ve Kamyon tablolarını ve bu tabloların attribute değerlerini oluşturalım.

CREATE TABLE `galeri`.`arac` (
 `arac_id` INT NOT NULL AUTO_INCREMENT,
 `firma` VARCHAR(45) NULL,
  PRIMARY KEY (`arac_id`));

Galeri adında yeni bir veritabanı ve araç adında yeni bir tablo oluşturduk. Bu tablonun attribute değerleri olarak arac_id ve firma değerlerini belirledik.
Daha sonra Otobüs tablomuzu ve attribute değerlerini oluşturalım.

CREATE TABLE `galeri`.`otobus` (
  `arac_id` INT NOT NULL,
  `seri` VARCHAR(45) NULL,
  `yıl` INT NULL,
  `kisi_sayisi` INT NULL,
  PRIMARY KEY (`arac_id`),
  CONSTRAINT `FK_ARAC` FOREIGN KEY (arac_id) REFERENCES `galeri`.`arac` (arac_id)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION);

Otobüs tablosunun attributelerini ise arac_id, seri, yıl ve kisi_sayisi olarak belirledik. arac_id attribute'unun Arac tablosunundan geldiğini ve bu tablo için de primary key olduğunu belirttik.
Son olarak Kamyon tablosunu da oluşturalım ve uygulamamızın Hibernate kısmına geçelim.

CREATE TABLE `galeri`.`kamyon` (
  `arac_id` INT NOT NULL,
  `model` VARCHAR(45) NULL,
  `kapasite_ton` INT NULL,
  PRIMARY KEY (`arac_id`),
  CONSTRAINT `FK_ARAC1`
  FOREIGN KEY (arac_id)  REFERENCES `galeri`.`arac` (arac_id)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION);

Tablolarımızı oluşturduktan sonra bu tablolara karşılık gelen java sınıflarını oluşturalım. Eşleme yaparken Hibernate anotasyonlarını kullanalım.

Arac tablosuna karşılık gelen Arac.java sınıfını oluşturalım.

Anotasyonlar kullanarak eşleme yapmayı daha önceki konularımızda görmüştük. Burada @Inheritance adında yeni bir anotasyon kullanarak inheritance durumunu belirteceğiz. @Inheritance anotasyonunu ve bu anotasyonun strategy attribute'unu kullanarak süper classın inheritance durumunu belirtiyoruz.

Daha sonra Arac sınıfından türeyen Otobus.java sınıfını oluşturalım.

Otobüs tablosuna karşılık gelen Otobüs.java sınıfı yukarıdaki gibi oluşturuyoruz ve Arac sınıfından extend ediyoruz. Tabloda karşılık gelen alanları anotasyonlarla belirtiyoruz. Burada bu sınıfın süper class ile bağlantısının primary key aracılığı ile olduğunu belirtmek için @PrimaryKeyJoinColumn anotasyonunu kullanıyoruz.
Şimdi de Kamyon tablomuza karşılık gelen Kamyon.java sınıfını oluşturalım.

Bu sınıfta da Otobüs.java sınıfında olduğu gibi süper classla bağlantısını belirtmek için @PrimaryKeyJoinColumn anotasyonunu kullanıyoruz. Bu sınıfı da Arac sınıfından extend etmeyi unutmuyoruz.
Java sınıflarımızı oluşturduktan sonra her zaman yaptığımız gibi bu sınıfları Hibernate konfigürasyon dosyamız olan hibernate.cfg.xml dosyamıza aşağıdaki gibi kaydediyoruz.

Son olarak bu sınıfları kullanabileceğimiz, üzerinde işlem yapabileceğimiz Main.java sınıfımızı oluşturuyoruz.

Main sınıfımızda ise her zaman yaptığımız gibi HibernateUtil sınıfını kullanarak yeni bir Session oluşturuyoruz. Daha sonra işlemlerimizi gerçekleştirerek veritabanımıza etki edecek olan transaction objemizi oluşturuyoruz.
Daha önceden oluşturduğumuz Araç, Otobüs ve Kamyon sınıflarından obje oluşturuyoruz. Bu oluşturduğumuz objeleri Session'ımıza kaydediyoruz ve işlemlerimizin veritabanını etkilemesi için transaction'ınımızı commit ediyoruz.
Bu transaction sonucunda Volvo, Mercedes, Neoplan ve Renault firmalarına ait araçlarımız oluşacaktır. Mercedes firmasına ait Travego adlı otobüsün yanı sıra Neoplan firmasına ait Starliner adlı otobüs ve bu otobüslerin bilgileri veritabanına işlenecektir. Ve son olarak Renault firmasına ait T440 modelinde yeni bir kamyon bilgisi veritabanına yazılacaktır.

Bu yazımda sizlere Hibernate teknolojisinde Table Per Subclass Inheritance konusundan bahsettim ve örnek uygulama oluşturarak bu inheritance durumunun nasıl olduğunu görmüş olduk.
Bir sonraki yazımda görüşmek üzere...

Referanslar:


4 Mayıs 2014 Pazar

Hibernate Annotations ile many-to-one association

Merhaba arkadaşlar,

Geçen hafta Hibernate anotasyonlarından bahsetmiştik. Bu hafta Hibernate anotasyonlarını kullanarak örnek bir proje oluşturacağım.

Öncelikle projemizde kullanacağımız Isci ve Departman adındaki tablolarımızı MySQL Workbench' de oluşturuyoruz.
Isci tablosunu ve attribute'lerini aşağıdaki gibi oluşturuyoruz.
Tablolar arasındaki ilişkimiz many-to-one olduğundan dolayı one taraf olan yani Departman tablosunun primary keyini many taraf olan Isci tablosuna foreign key olarak ekliyoruz.
Isci tablomuzu oluşturduktan sonra Departman tablomuzu ve attribute'lerini aşağıdaki gibi oluşturuyoruz.

Tablolarımızı oluşturduktan sonra içlerine birkaç veri ekliyoruz.
Verileri girerken many-to-one ilişkimize dikkat ediyoruz. Bu ilişkide aynı departmanda birden fazla işçi çalışabilir ve bir işçi sadece bir departmanda çalışabilir. 
Tablolarımızı oluşturduktan sonra java sınıflarımızı oluşturacağız.
Isci tablosuna karşılık gelen Isci.java sınıfımızı aşağıdaki gibi oluşturuyoruz.

Veritabanımızda oluşturduğumuz Isci tablosunun adını ve sütunlarını bu sınıf içerisinde belirtiyoruz.
Tablo adını @Table(name="isci") anotasyonuyla belirtiyoruz. Tablo sütunlarını ise @Column(name="ad") anotasyonu ile belirtiyoruz. Tablomuzun primary keyini ise @Id, @GeneratedValue ve @Column(name="isciID") anotasyonları ile belirtiyoruz. Many-to-one ilişkisini @ManyToOne anotasyonu ve Departman tablosundan gelen foreign key departmanID'yi @JoinColumn(name="departmanID") anotasyonu ile belirtiyoruz.
Daha sonra Isci sınıfımızın default constructor'ını ve parametreli constructor'ını yazıyoruz. Ve son olarak tablomuzun sütunlarının getter&setter methodlarını yazıyoruz.
Isci.java sınıfımızı oluşturduktan sonra Departman tablomuza karşılık gelen Departman.java sınıfımızı oluşturalım.
Departman sınıfımızı yukarıdaki gibi oluşturduktan sonra ana sınıfımız olan Main.java sınıfını oluşturalım ve üzerinde işlem yapalım.
Session factory oluşturmak için HibernateUtil.java sınıfını kullanıyorduk bu projemize onu da dahil ediyoruz.

Main sınıfımızda session oluşturup, transaction başlatıyoruz. Daha sonra Departman sınıfımızdan obje oluşturup, setDepartmanAdi() methodunu kullanarak "Ulastirma" adında yeni bir departman oluşturuyoruz.
Daha sonra oluşturduğumuz bu objeyi sessiona kaydediyoruz.
Yeni bir Isci oluşturmak için ise Isci sınıfımızdan obje oluşturup constructorına ilgili değerleri yazıyoruz. Bu yolla Ali Akyüz ve Mehmet Öztürk adında iki yeni işçi oluşturuyoruz. Oluşturduğumuz bu işçilere daha önceden oluşturduğumuz "Ulaştırma" departmanına kaydediyoruz. Daha sonra yaptığımız bu değişiklikleri veritabanına göndermek için transaction.commit() komutunu kullanıyoruz.
Sonraki adım olarak oluşturduğumuz sınıfları hibernate configuration dosyamıza belirtiyoruz.
hibernate.cfg.xml
Ve artık projemizi çalıştırabiliriz. Sonuç olarak Ali Akyüz ve Mehmet Öztürk adında iki yeni işçi ve Ulaştırma adında yeni bir departman oluşacak ve bu iki işçi Ulaştırma deparmanına atanacaklardır.

Bugün Hibernate anotasyonlarını kullanarak nasıl many-to-one ilişki oluştulur örnek proje üzerinde görmüş olduk. Haftaya bir başka konu ile birlikte olacağız. Takipte kalmayı ihmal etmeyiniz...


27 Nisan 2014 Pazar

Hibernate Annotations

Merhaba arkadaşlar,

Bu yazımda sizlere Hibernate Annotation'lardan bahsedeceğim. Bildiğiniz üzere bundan önceki konularımızda veritabanımızda bulunan tabloları eşleme yapmak için  XML dosyaları kullandık. Bu eşleme işleminin bir diğer yöntemi de Hibernate Annotation'ları kullanarak eşleme yapmaktır. Peki bu Hibernate Annotation'lar nedir ve nasıl kullanılır? onlardan bahsedelim.

Öncelikle bu annotation'ları kullanabilmek için ilgili jar dosyalarını indirmemiz gerekiyor. Bunlar hibernate-annotations.jar, hibernate-commons-annotations.jar ve ejb3-persistence.jar dosyalarıdır. Daha önceki haftalarda Hibernate projeleri için gerekli olan jar dosyalarını indirdik ve Hibernate adında bir User Library oluşturmuştuk. Oluşturduğumuz bu User Library içinde yukarıda bahsettiğim jar dosyaları da bulunuyordu. Eğer User Library oluşturmadıysanız ilgili jar dosyalarını projenize sağ tıklayıp Build Path ->Configure Build Path -> Libraries ->Add External JARs adımlarını izleyerek ekleyebilirsiniz.

Jar dosyalarımızı ekledikten sonra veritabanımızda "Isci" adında bir tablo oluşturalım.

create table Isci(
id INT NOT NULL auto_increment, 
ad VARCHAR(20) default NULL,
soyad VARCHAR(20) default NULL,
maas INT default NULL,
PRIMARY KEY (id) );

Şimdi bu tablomuzu Hibernate Annotaiton'ları kullanarak eşleyelim.


Öncelikle veritabanımızdaki tablomuzun isminde yeni bir java sınıfı oluşturuyoruz. EJB 3 standart anotasyonlarını içeren javax.persistence paketini import ediyoruz ve sınıf ismimizin üstüne @Entity ve @Table anotasyonlarımızı yazıyoruz.

@Entity anotasyonu kullanarak Isci sınıfımızın bir Entity Bean olduğunu belirtiriz. Peki Entity Bean nedir? kısaca değinecek olursak. Entity Bean bir veritabanındaki iş varlık nesnesini temsil eder. Yani biraz daha açacak olursak veritabanımızda bulunan her bir tablo bir Entity Bean'e karşılık gelir. Bu tablolarımızdaki her bir satır da Entity Bean Instance'a karşılık gelir. Entity Bean veriyi objeleştirir ve üzerinde daha kolay işlem yapmamızı sağlar. Entity Bean'ler kalıcıdır, primary key'leri vardır, paylaşımlı erişime izin verir ve diğer entity bean'ler ile ilişki oluşturulabilir. Ayrıca Entity Bean'lerin parametresiz constructor'u olmak zorundadır.

@Table anotasyomunuz ise veritabanımızdaki tablomuzun ismine karşılık gelir. Name atribute'nun yanı sıra catalogue, schema ve unique constraint attribute'lerini de içerir. Biz name attribute'unu kullanarak tablo ismimizi belirteceğiz.

Kullandığımız diğer anotasyonlardan @Id ve @GeneratedValue anatosyonları ise yukarıda Entity Bean'lerden bahsederken onların primary key'lerinin olduğuna değinmiştik. Entity Bean olan Isci sınıfımızın primary key'ini belirtiyoruz.

@Column anotasyonu ise tablomuzda yer alan sutun değerlerine karşılık gelir. Bu anotasyonun name attribute'unun yanı sıra length, nullable, unique attribute'lerini de alır.

Daha sonra tablomuzdaki attribute değerlerine karşılık gelen değişkenlerimizin getter&setter methodlarını oluşturuyoruz. Böylece Hibernate anotasyonlarını kullanarak tablomuzu eşlemiş olduk. Oluşturduğumuz bu sınıfı daha öncede bahsettiğimiz hibernate configuration dosyamıza (hibernate.cfg.xml) mapping class olarak belirtiyoruz.
<mapping class="com.hibernate.example.Isci" />

Buraya kadar veritabanımızda bulunan tablomuzu Hibernate anotasyonları kullanarak nasıl eşleyeceğimizi görmüş olduk. Haftaya anotasyonlar kullanarak daha detaylı bir örnek proje oluşturmayı planlıyorum. Takipte kalmaya devam edin...

20 Nisan 2014 Pazar

Many-to-many Association XML Mapping

   Merhaba arkadaşlar,

   Bugün sizlere aralarında many-to-many ilişkisi bulunan öğrencilerin ve onların almış olduğu derslerin bilgisinin tutulduğu iki tablo kullanarak örnek bir proje oluşturacağım.

   Öncelikle veritabanı aracımızda 'Ogrenciler' ve 'Dersler' adında iki tablo oluşturacağız. Ben veritabanı aracı olarak MySQL kullandığımı daha önceden belirtmiştim. Kendi MySQL WorkBench'imde 'Ogrenciler' ve 'Dersler' adında iki tablo oluşturdum.

CREATE TABLE `uyeler`.`ogrenciler` (
`OgrenciId` INT NOT NULL AUTO_INCREMENT,
`OgrenciAdSoyad` VARCHAR(45) NULL,
PRIMARY KEY (`OgrenciId`));

CREATE TABLE `uyeler`.`dersler` (
`DersId` INT NOT NULL AUTO_INCREMENT,
`DersAdi` VARCHAR(45) NULL,
PRIMARY KEY (`DersId`));

Yukarıdaki tabloları oluşturduktan sonra tablolar arasındaki ilişkinin many-to-many olmasından dolayı üçüncü bir ilişki tablosu oluşturmamız gerekiyor. 'Kayit' adında yeni bir ilişki tablosu oluşturacağız.

CREATE TABLE `uyeler`.`kayit` (
`DersId` INT NOT NULL,
`OgrenciId` INT NOT NULL,
PRIMARY KEY (`DersId`, `OgrenciId`),
CONSTRAINT `DersId`
FOREIGN KEY (DersId)
REFERENCES `uyeler`.`dersler` (DersId)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `OgrenciId`
FOREIGN KEY (OgrenciId)
REFERENCES `uyeler`.`ogrenciler` (OgrenciId)
ON DELETE NO ACTION
ON UPDATE NO ACTION);

Daha önceden oluşturduğumuz 'Ogrenciler' ve 'Dersler' adındaki tabloların primary keylerini bu tabloda foreign key olarak belirledik.
Tablo yapılarımızı oluşturduktan sonra içlerine kayıt ekleyelim.

                       'Dersler' tablosu                                            'Ogrenciler' tablosu 
   
       

Şimdi bu iki tablo arasındaki many-to-many ilişkiyi gösteren 'Kayit' tablosuna kayıt ekleyelim.

                                                        'Kayit' tablosu
                                        

Veritabanına kayıt ekleme işlemlerini tamamladıktan sonra Hibernate kısmına geçelim. Öncelikle boş bir proje açıyoruz. Açtığımız projeye daha önceki yazılarımda değindiğim Hibernate kütüphanelerini içeren User Libraryimizi dahil ediyoruz. Daha sonra veritabanımızda oluşturduğumuz tablolarımızın POJO sınıflarını oluşturuyoruz. 'Dersler' tablosunu eşlemek için aynı isimli bir java sınıfı oluşturuyoruz.

Dersler.java


Öğrenci bilgisini içeren 'Ogrenciler' adındaki tabloyu eşlemek için Ogrenciler adında yeni bir java sınıfı oluşturuyoruz.
Ogrenciler.java


Daha sonra veritabanında oluşturduğumuz tabloları eşlemek için  XML mapping dosyalarını oluşturuyoruz.

Dersler.hbm.xml

'Dersler' tablosunun XML eşlemesini tamamladıktan sonra 'Ogrenciler' tablosunun XML eşlemesini yapıyoruz. Bu işlem için Ogrenciler.hbm.xml adında yeni bir XML dosyası oluşturuyoruz.

Ogrenciler.hbm.xml

XML mapping işlemini tamamladıktan sonra Hibernate configuration dosyamızı oluşturuyoruz.

hibernate.cfg.xml


Oluşturduğumuz bu xml dosyasına veritabanı bağlantı bilgilerimizi ve daha önceden oluşturduğumuz xml mapping dosyalarımızın kaynağını belirtiyoruz.

Daha sonra SessionFactory oluşturarak Hibernate işlemlerimizi sağlayan HibernateUtil adında yeni bir sınıf oluşturuyoruz.

HibernateUtil.java


Yukarıda belirttiğimiz tüm bu işlemlerden sonra ana sınıfımız olan Main sınıfında yeni ders kayıtları ve öğrenci kayıtları oluşturup, bu kayıtlar arasındaki ilişkiyi belirten kodu yazıyoruz. 

Main.java


Kültürel Etkinlik ve Almanca adında yeni 2 ders kaydı oluşturduk. Aynı zamanda Zeki Bahar ve Kamil Gunes adında iki yeni öğrenci oluşturduk ve bu öğrencilerin Kültürel etkinlik ve Almanca derslerini almalarını sağladık. Buradan da anlaşılacağı üzere bir dersi birden fazla öğrenci alabilir ve bir öğrenci birden fazla ders alabilir (many-to-many ilişkisi).
Bu işlemler sonucunda veritabanımızdaki tablolarımızın son hali şu şekilde olacaktır.

                        Dersler tablosu                                             Ogrenciler tablosu

  
                                         
                                                                       Kayit tablosu

Burada yazıma son veriyorum. Bir sonraki yazımda görüşmek üzere. Esen kalın...

11 Nisan 2014 Cuma

One-to-one(1-1) XML Mapping 2.Bölüm

   Merhaba arkadaşlar,

   Bu hafta bir önceki yazımda bahsettiğim Mapping kavramı ve one-to-one(1-1) XML Mapping yapısı için oluşturduğumuz uygulamamıza devam edeceğiz. Önceki yazımızda POJO sınıflarımızı ve XML mapping dosyalarımızı oluşturmuştuk. Bu hafta ise yeni bir işçi ve 1-1 ilişkide ona karşılık gelen adresin eklenmesi ve işçi bilgilerinin güncellenmesi gibi konuların üzerinde duracağız. Tüm bu işlemleri yapmak için öncelikle "Uygulama" adında yeni bir class oluşturuyoruz.

public class Uygulama {
          private static SessionFactory factory;

      public static void main(String[] args) {
    // hibernate.cfg.xml dosyasındaki ayarlara ait bir session factory  yaratıyoruz.
           factory = new Configuration().configure().buildSessionFactory();

   //üzerinde işlem yapabilmek için bulunduğumuz sınıftan bir nesne oluşturuyoruz.
          Uygulama obj = new Uygulama();

  //yeni bir işçi ve ona ait olan adres eklemek için aşağıda oluşturdurduğumuz adresEkle() ve    isciEkle() methodlarına parametre gönderiyoruz.
          Adres adres1= obj.adresEkle("Yenibaglar","Eskisehir","26000");
          Integer isciId1 = obj.isciEkle("Ali", "Ak", 2500, adres1);

          Adres adres2= obj.adresEkle("Şirintepe","Eskisehir","26000");
          Integer isciId2 = obj.isciEkle("Veli", "Al", 1500, adres2);

          obj.isciMaasGuncelle(isciId1,3000);   //yukarıda oluşturduğumuz "Ali Ak" isimli işçinin maaşını 3000 olarak güncellemek için  isciMaasGuncelle() methoduna işçinin id'si ile yeni maaş değerini gönderiyoruz.

//veritabanımızda bulunan Adres tablomuza yeni bir kayıt ekleme için adresEkle() methodu oluşturduk.
public Adres adresEkle(String mahalle, String sehir, String postakodu) {
        //daha önceden oluşturduğumuz session factory üzerinde yeni bir session açıyoruz.
        Session session = factory.openSession();
Transaction trans = null;
Integer adresId = null;
Adres adres = null;
try{
trans = session.beginTransaction(); //açtığımız sessionda transaction işlemini başlatıyoruz.
        //yeni bir adres ekleyeceğimiz için Adres nesnesi oluşturuyoruz 
                adres = new Adres(mahalle, sehir, postakodu);
       //oluşturduğumuz adres nesnesini sessiona kaydediyoruz.
adresId = (Integer)session.save(adres);
       //veritabanında yeni bir adres kaydı eklenmesi için transaction işlemimizi veritabanına   gönderiyoruz.
trans.commit();
}catch (HibernateException e) {
       //eğer transaction sırasında bir hata oluşursa yapılan değişikliği geri almak için rollback yapıyoruz.
if (trans!=null) trans.rollback();
e.printStackTrace();
}finally {
session.close();  //işlemimizi bitirdikten sonra daha önceden açtığımız sessionı kapatıyoruz.
}
return adres;
}

Yeni bir adres bilgisi eklemek için yaptığımız işlemlerin aynısını yeni bir işçi eklemek içinde yapıyoruz. Yeni bir işçi eklemek için isciEkle() methodunu oluşturuyoruz.

public Integer isciEkle(String ad, String soyad, int maas, Adres adres){
Session session = factory.openSession(); 
Transaction trans= null; 
Integer isciId = null;
try{ 
trans= session.beginTransaction(); 
Isci isci = new Isci(ad, soyad, maas, adres); 
isciId = (Integer) session.save(isci);
trans.commit(); 
}catch (HibernateException e) { 
if (trans!=null) trans.rollback(); 
               e.printStackTrace(); 
}finally { 
                 session.close(); 
return isciId;
 }

Şimdiye kadar yeni bir işçi ve ona ait adres bilgisini oluşturduk ve veritabanımıza ekledik. Peki şimdi de veritabanımıza kaydettiğimiz işçilerin maaşlarını güncelleyelim.

public void isciMaasGuncelle(Integer IsciId, int maas){ 
Session session = factory.openSession(); 
Transaction trans= null;
try{ 
trans = session.beginTransaction();
Isci isci = (Isci)session.get(Isci.class, IsciId);
isci.setMaas(maas);   //yeni maaş değerini atayalım.
session.update(isci);   //işçi nesnemizi güncelleyelim.
trans.commit();       //yaptığımız değişikliği veritabanına gönderelim.
}catch (HibernateException e) {
if (trans!=null) trans.rollback(); 
               e.printStackTrace(); 
}finally {
               session.close(); 
}
}
}
}

Bugünkü uygulamamızda daha önceden eşleme(mapping) işlemini yaptığımız tablolara yeni kayıt ekleme ve kayıt güncelleme işlemlerini gerçekleştirdik. Bir sonraki yazımda görüşmek üzere...