ArÅŸiv

‘Java Teknolojileri’ kategorisi için arÅŸiv

Hibernate Criteria API – Restrictions.sqlRestriction metodu

Cumartesi, 01 Mar 2014 Yorum yapılmamış

Hibernate Criteria API’de hazırlanmakta olan sql’e “native sql” ekleyebilmemizi saÄŸlayan özel bir metot bulunuyor; Restrictions.sqlRestriction(). Özellikle veritabanı fonksiyonlarından faydalanmak istediÄŸimizde veyahut da düz sql ile daha kolay halledebileceÄŸimizi düşündüğümüz durumlarda kullanışlıdır da.

Fakat bu metodun tek parametre alan hali sorunlara yol açabilir. EÄŸer kullanıcı tarafından(ekrandan, dosyadan vs.) girilen deÄŸer bu sql ifadesine doÄŸrudan parametre olarak ekleniyorsa muhtemel bir “sql injection” veya yapısı bozulan bir sorgu(missing right/left parenthesis, invalid character vs.) ile karşılabilirsiniz.

Bu durumlardan sakınmak için metodun parametrelerinin tipini de belirtebildiğimiz versiyonunu kullanmak gerek.

//...
Criterion criterion = Restrictions.sqlRestriction("NLS_LOWER(USER_NAME, 'nls_sort = XTurkish') like  '" + userName + "'");
//...

ÅŸeklinde parametreyi sql ifadesine doÄŸrudan eklemek yerine

//...
//Tek parametre olmasi durumundaki kullanim
Criterion critCode = Restrictions.sqlRestriction("NLS_LOWER(USER_NAME, 'nls_sort = XTurkish') like ? ", userName, StandardBasicTypes.STRING);
//...
//Birden fazla parametre olmasi durumundaki kullanim
Object[] parameterValues = new Object[]{userName, userSurname};
Type[] parameterTypes = new Type[]{StringType.INSTANCE, StringType.INSTANCE};
criteria.add(Restrictions.sqlRestriction("NLS_LOWER(USER_NAME, 'nls_sort = XTurkish') like ? or NLS_LOWER(USER_SURNAME, 'nls_sort = XTurkish') like ? ", parameterValues, parameterTypes));
//...

şeklindeki kullanım daha doğru olur.

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail

Refactoring

Pazar, 23 Åžub 2014 3 yorum

Büyük oranda Martin Fowler’ın “Refactoring – Improving The Design of Existin Code” kitabından faydalandığım Refactoring eÄŸitiminin sunumunu paylaÅŸayım dedim, bir faydası dokunması umuduyla.

Martin Fowler‘ın tanımıyla Refactoring yazılımın gözlemlenen davranışlarını deÄŸiÅŸtirmeyen, fakat iç yapısını deÄŸiÅŸtiren bir dizi küçük iyileÅŸtirmedir.

Sunum kabaca şu başlıklardan oluşuyor;

  • Refactoring Nedir ?
  • Neden Refactor Etmek Gerek ?
  • Ne Zaman Refactor Etmek Gerek ?
  • Nasıl Refactor Etmek Gerek ?
  • Refactoring KataloÄŸu

Not : “Refactoring”, “refactor etmek” gibi tabir ve terimlere Türkçe’de getireceÄŸim karşılıklar kulak tırmayalayabileceÄŸi için oldukları gibi kullanmak durumunda kaldım.

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail

Google Guava – EventBus (Observer Pattern Uygulaması)

Cumartesi, 25 May 2013 Yorum yapılmamış

Google’ın faydalı kütüphanesi Guava‘da geniÅŸ kullanıma müsait, esnek ve sade bir observer pattern uygulaması mevcut; EventBus. SaÄŸladığı diÄŸer bazı avantajlarla beraber düşününce birden observer pattern ihtiyacı olan her duruma uygulanabilir geldi gözüme. Bir nevi “silver bullet” gibi. Elbette ki deÄŸil, yok öyle bir ÅŸey.

EventBus sınıfı observer pattern‘deki olay yayınlayıcısı sınıfa (publisher) karşılık geliyor. EventBus’ın yayınlayacağı olaylardan haberdar olmak isteyen sınıflar (subscriber) bu sınıfa kayıt oluyorlar. Kayıt olmuÅŸ bu sınıflar EventBus bir olay yayınladığında @Subscribe ile belirtilmiÅŸ, tek parametresi yayınlanan olayın tipinde bir parametre olan metotları ile bu olayı yakalayabiliyorlar. EventBus haber vereceÄŸi metodu/metotları bulurken sınıf hiyerarÅŸisini dikkate alıyor. Bu durum çok biçimliliÄŸe elveriÅŸli, esnek kod yazabilmek açısından oldukça kullanışlı.

Bir örnek üzerinden anlatacak olursam; PolitikaHaberi, SporHaberi, HavaDurumuHaberi tipinde ve her biri Haber‘den türemiÅŸ sınıflar olsun. @Subscribe ile bildirilmiÅŸ ve tek parametresi PolitikaHaberi olan bir metot PolitikaHaberi türünde haberleri dinleyebilir. Genel bir ihtiyaç durumunda her türlü haber dinlenmek isteniyorsa mesela, bu iÅŸ @Subscribe ile bildirilmiÅŸ ve tek parametresi Haber olan bir metot ile yapılabilir.

...
@Subscribe
public void listenToSportsNews(SportsNews sportsNews){
	System.out.println("Hearing from..." + sportsNews.getType());
	for(String news : sportsNews.getNews()){
		System.out.println(news);
	}
		
}
...

@Subscribe
public void listenToNews(News newsNewsNews){
	System.out.println("Hearing from any type of news. This time : " + newsNewsNews.getType());
	for(String news : newsNewsNews.getNews()){
		System.out.println(news);
	}
	
}
...
...
//Create newsEventBus object
		EventBus newsEventBus = new EventBus("News from Earth !");;
		
		//Create newsBulletin
		NewsBulletin newsBulletin = new NewsBulletin();
		
		//Create newsListener, and register to the newsEventBus (start listening to)
		NewsListener newsListener = new NewsListener();
		newsEventBus.register(newsListener);
		
		//Publish news
		newsEventBus.post(newsBulletin.publishPoliticsNews());
		newsEventBus.post(newsBulletin.publishSportsNews());
		newsEventBus.post(newsBulletin.publishWeatherNews());
		
		//Unregister from the newsEventBus (stop listening to)
		newsEventBus.unregister(newsListener);		
...

Burada bilinmesi gerek yukarıda da söylediğim gibi EventBus bir olay yayınladığında çağıracağı metotları sınıf hiyerarşisini dikkate alarak buluyor. Bu yüzden SporHaberi yayınlandığında bunu hem spor haberi dinleyen hem de haber dinleyenler duymuş oluyor. Daha veciz bir ifadeyle Haber dinleyen her türlü haberi, SporHaberi dinleyen yalnızca spor haberini duyuyor.

EventBus sınıfı uygulamanın ihtiyacına bağlı olarak bir kere/tane (singleton) veya birden fazla oluşturulabiliyor. Farklı bağlamları olan her bir olay grubu için bir EventBus tanımı yapılabilir pekala. Daha fazla uzatmadan kaynakları işaret ederek bitireyim. Google Guava kütüphanesine şuradan erişilebilir. Detaylı bilgi ve açıklama için Google geliştirici sayfası da şurada. Eli yüzü daha düzgün bir örnek uygulama da burada

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail

Eclipse – Customize View

Çarşamba, 12 Ara 2012 Yorum yapılmamış

Eclipse’te yüklü eklenti sayısı arttıkça kalabalıklaşıp, göz tırmalar hale gelen iki durumdan kurtulmanın yönteminden bahsedeyim.

Birincisi üst menüdeki buton kalabalığı. Windows->Customize Perspective menüsünden Tool Bar Visibility sekmesinden aktif olarak kullanılan butonlar seçilip, sadece bu butonların görünmesi sağlanabiliyor.

Ä°kincisi de saÄŸ tık menülerindeki seçenek kalabalığı. Yine aynı ÅŸekilde Windows->Customize Perspective menüsünün Menu Visibility sekmesinden menülerde hangi öğelerin gösterileceÄŸi seçilebiliyor. Mesela projedeki bir klasör üzerinde saÄŸ tık yapıp “New” denildiÄŸinde on yüz bin milyon dosya türü gelmesin istenilebilir gayet insani bir tavırla. Bunun için File->New seçeneÄŸinden istenenler seçilerek daha sade bir menü oluÅŸturulabilir.

eclipse-customize-perspective-menu-toolbar

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail

Hibernate Blob Tipi – Criteria API Example uyuÅŸmazlığı

Pazartesi, 10 Ara 2012 Yorum yapılmamış

Geçenlerde epeyce vaktimi alan bir hatayı nasıl çözdüğümüzden bahsedeyim. Olur da benzer bir hata ile cebelleşen birileri arar da denk gelir. Üşenme yaz, kullanıcı bilmezse Google bilir.

Bütün mesele bir dosyayı veritabanında BLOB olarak tanımlanmış bir kolona yazmaktı aslında. Dosya içeriğini byte[] tipinde değil de, java.sql.Blob tipinde tanımlamak gerektiğini öğrendim bu arada, aksi durumda eşlemede tip uyuşmazlığı hatası alınıyor.

Entity sınıfı : File.java

...
private Blob fileContent;
//private byte[] fileContent; 
...

Hibernate eşleme(mapping) dosyası : File.cfg.xml

...
<property name="fileContent" type="blob" column="FILE_CONTENT" />
...

(Hibernate Annotation ile aynı hata oluşuyor mu bilmiyorum bu arada)

şeklinde eşledim dosyanın içeriğini. Fakat testleri çalıştırdığımda

java.sql.SQLSyntaxErrorException: ORA-00932:
inconsistent datatypes: expected – got BLOB

ÅŸeklinde bir hata ile karşılaÅŸtım. Uzunca bir süre debelendikten sonra, basit bir hibernate projesi oluÅŸturup, önce en güncel hibernate kütüphaneleri ile sonra da 3.6 sürümü kütüphaneleri ile test ettim. Herhangi bir sorun olmadan yukarıdaki eÅŸlemelerle dosyayı kaydedebildim. Forumlarda benzer bir sorunla karşılaÅŸmış olanların belirttiÄŸi hibernate.cfg.xml‘de çeÅŸitli ayar deÄŸiÅŸiklikleri yapmak, hibernate ve bağımlı olduÄŸu kütüphanelerin sürümlerini incelemek, debug loglarını satır satır incelemek ve sair derken uzunca bir maratondan sonra oyunun sonunu getirdik, prensesi kurtardık.

Sorunun kaynağı Blob tipi bir alana sahip sınıf için Hibernate Criteria API’nin Example yapısı ile arama yapmak imiÅŸ. Böyle bir durumda yukarıdaki gibi bir tip uyuÅŸmazlığı hatası alınıyor. Çözüm olarak ilk akla gelen Blob tipindeki alanı excludeProperty olarak belirtip, kriter listesinin dışında bırakmaktı tabi ki.

...
File file = new File();
file.setName("XFile");
...
//set other file properties
...
//Create an example to search for
Example example = Example.create(file)
//but exclude the property named "fileContent"
                  .excludeProperty("fileContent");  

List<File> results = session.createCriteria(File.class).add(example).list();
...

Muhtemelen benzer hatayı Clob tipi için de verecektir. Akıllarda buluna, gaflete düşülmeye…

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail

Eclipse Performans İpuçları

Cuma, 16 Kas 2012 Yorum yapılmamış

Oldukça fazla sayıda sınıfın bulunduÄŸu bir projeyi açtığımda ortaya çıktı yavaÅŸlık sorunu. Neydi bu ayarlar, ne deÄŸildi yahu derken Google yolları gözüktü yine. Tabi bir de malum, arama sonuçlarını ayıklamak. Eclipse’in çalışmasını ve açılışını hızlandırmak için genel kabul gören bu bir kaç maddeyi derleyip, toplayayım dedim. Aslında bir dolu blogda benzer bilgiler mevcut ya, olsun. Hem baktım da site film bloÄŸu olup çıkacak yakında, bir iki teknik dokunuÅŸ yapayım madem…

eclipse.ini Önerileri

Önce şunu söyleyeyim ki, bu dosyada yapılan değişiklikler Eclipse açılışında hata alınmasına sebep olabilir. Bu yüzden önce bir yedek almak lazım.

Başlangıç parametrelerinin bulunduğu bu dosya Eclipse’in kurulu olduğu dizinde bulunur. Bu parametrelere verilebilecek değerler bilgisayarın donanım özelliklerine göre değişir.

  • -XX:PermSize ve -XX:MaxPermSize : Bu parametreler Eclipse’in kullanacağı JVM’in Perm Space hafıza alanının baÅŸlangıç sınırını ve üst sınırını belirliyor. Perm Space demiÅŸken, bu alan sınıf ve metot tanımlarının, bilgilerinin (sınıflardan oluÅŸturulan objelerin deÄŸil!) tutulduÄŸu hafıza alanı. Dolayısıyla çok fazla sınıf bulunan bir “workspace” de yaÅŸanabilecek Out of Memory : perm gen space error türü hafıza sorunlarını gidermede faydası olabilir.
  • -Xms ve -Xmx : Bu parametreler Eclipse’in kullanacağı JVM’in temel hafıza alanı olan Heap Space deÄŸerlerinin baÅŸlangıç sınırını ve üst sınırını belirliyor. Örnek olarak 4GB RAM bulunan bir bilgisayarda bu deÄŸer 1024’e kadar çıkarılabilir. Eclipse -Xms’de belirtildiÄŸi kadar hafıza ile çalışmaya baÅŸlıyor ve gerektiÄŸinde bu deÄŸeri -Xmx’e kadar arttırıyor. Bu arada, Eclipse’in gereken durumlarda kullandığı hafızayı arttırması iÅŸi maliyetli olabileceÄŸinden, bu iki deÄŸerin birbirine olabildiÄŸince yakın olmasında fayda olduÄŸu söyleniyor.
  • -Xverfiy:none : Bu parametre ile Eclipse’e, “açılırken yüklediÄŸin .class dosyalarını doÄŸrulama iÅŸlemine(validation) tabi tutma” ÅŸeklinde bir ayar verilebilir. Ki bu da açılış hızına olumlu etki yapar.

Eclipse’in Açılış ve Çalışma Hızını Arttırabilecek Diğer Öneriler

  • Window->Preferences->Validation menüsünden gerekli olmadığını düşündüğümüz validator‘leri devre dışı bırakmak
  • Window->Preferences->General->Editors->Spelling menüsünden çok da gerekli olmadığını düşündüğümüz Spell Check‘leri kapatmak
  • -Window->Preferences->General->Startup and Shutdown menüsünden Eclipse açılırken baÅŸlatılmasına gerek olmadığını düşündüğümüz eklentileri devre dışı bırakmak

Etkisinin yukarıdakiler kadar olması beklenmese de bunların dışında ; Kullanılmayan projeleri devre dışı bırakmak, kullanılmayan görüntüleme pencerelerini ve perspektifleri kapatmak, ve elbette Eclipse’in güncel versiyonlarını kullanmak yapılabilecekler arasında.

Tabi bir de paraya kıyıp bilgisayarın RAM’i arttırılabilir, para var huzur var arkadaÅŸ…

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail

Java Enum Reverse Lookup

Perşembe, 17 May 2012 Yorum yapılmamış

Java 1.5 sürümü ile birlikte gelen Enum sınıfı genel itibariyle sabit verileri tanımlamak için kullanılır. 1.5 öncesi static final olarak tanımlanan sabit verilere denk gelir bir nevi. ÇoÄŸu zaman da bu sabit verilerle iliÅŸkilendirilmiÅŸ bir kod eÅŸlemesi yapılır. Döviz-döviz kodu, elemen-element simgesi, durum-durum kodu gibi…Bu kod tanımı Enum sınıfın yapılandırıcısına parametre geçilerek yapılır.

public enum Gender {
	Male("M"),
	Female("F");

	private String code;

	private Gender(String code) {
		this.code = code;
	}

	public String getCode() {
		return code;
	}
}

Herhangi bir enum değerin code alanına

Gender.Male.getCode()

ÅŸeklinde eriÅŸebiliriz.

Bahsetmek istediÄŸim ise bunun tam tersi durumda yani code alanından enum deÄŸere eriÅŸmek istediÄŸimiz durumda ne yapılabileceÄŸi. Bu durumun tam karşılığı “enum reverse lookup”.

public enum Month {
	JAN(1),FEB(2),MAR(3),APRIL(4),MAY(5),JUN(6),JUL(7),AUG(8),SEP(9),OCT(10),NOV(11),DEC(12);
	private int code;

	private Month(int code) {
		this.code = code;
	}

	public int getCode() {
		return code;
	}

}

şeklinde bir enum sınıfı olduğunu varsayarsak code alanından Month enum değerine

public Month getMonthFromCode(int code){
  for (Month month : Month.values()){
	  if (month.getCode() == code)
		  return month;
  }
  return null;

ÅŸeklinde eriÅŸilebilir.

Fakat her seferinde bir for döngüsü ile enum deÄŸerleri içinde dönmek yerine static bir Map tanımlayıp, bütün enum deÄŸeri-kod eÅŸleÅŸmeleri bu Map‘e koyularak, istenen enum deÄŸere her seferinde tek hamlede de eriÅŸlebilir. Şöyle ki;

public enum Month {

JANARY(1),FEBRUARY(2),MARCH(3),APRIL(4),MAY(5),JUNE(6),JULY(7),AUGUST(8),SEPTEMBER(9),OCTOBER(10),NOVEMBER(11),DECEMBER(12);
	private int code;

	private static Map enumCodeMap;
	static {
		enumCodeMap = new HashMap();
		for(Month month : Month.values()){
			enumCodeMap.put(month.getCode(), month);
		}
	}

	public static Month getMonthFromCode(int code){
		return enumCodeMap.get(code);
	}

	private Month(int code) {
		this.code = code;
	}

	public int getCode() {
		return code;
	}

}

şeklindeki bir enum tanımı sonrası

Month month = Month.getMonthFromCode(6);
//JUNE

denilebilir. Bu şekilde static bir tanım ile JVM, Month enum sınıfını yüklediğinde hazır hale gelmiş olan enumCodeMap değişkeni üzerinden her seferinde teknik olarak da, kod satırı olarak da tek hamle ile istenen enum değere erişilmiş olur.

Düzenleme : Bu durumla tam olarak örtüşen bir örnek, periyodik cetveldeki elementlerin tutulduÄŸu bir enum sınıfı olabilir. Element adı enum deÄŸeri, element simgesi kod olacak ÅŸekilde oluÅŸturulmuÅŸ olan bir Element enum sınıfı düşünülebilir. Altın’ın simgesi olan “Au” ya eriÅŸmekten ziyade, simgesi “Au” olan elemente eriÅŸmek lazım olduÄŸu durumlarda bu yöntem kullanılabilir

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail
Kategoriler:Java Etiketler:, , ,