Hibernate Filters

Jboss Seam ile birlikte kullanımımıza sunulan hibernate, yazılım geliştirme sürecinde veritabanında yapılan işlemlerin tutarlılığın kontrolünü sağlamanın yanında bir çok faydalı araçları ile yazılım geliştirme sürecinide kolaylaştırmaktadır.

Bunlardan bir tanesinede hibernate filter ismini verdiğimiz,  entity bazlı sorgulama işlemlerinde otomatik olarak belirli alanlara ve verilen değerlere göre sorguları filtrelemek için kullandığımız araçtır. Hibernate filter, HQL cümlesini SQL'e çevirirken sorgu içine önceden tanımladığımız  koşulları sorguya AND olarak dahil eder.

Bu yazımda hibernate filter'i seam üzerinde nasıl kullanacağımıza bakacağız. Bunun için örnek olarak yazılımızın bazı entitleri Customer Entity'si ile customer_id üzerinden bağ kurmuş olsun. Sistemde oturum açan müşterinin sayfalarda dolaşırken bu entitylere bağlı tablolardan gelen verilerin mutlaka bu müşteriye ait olması gereklidir şeklinde bir senaryomuz olsun.

Normal şartlarda bu işlemi yazdığımız sorgu cümlelerine koşul olarak kendimiz customer_id'i yazarız. Bu işlemi Hibernate Filter sayesinde otomatik olarak yaptırabiliriz. Hibernate Filter'ın sağladığı bir diğer noktada bu şekilde neredeyse her sorguya girebilecek bir koşulun ileride herhangi bir alan alan adı vb. değişikliği sonucunda tek bir noktadan değişikliği yapmayı sağlayarak gözden kaçabilecek problemleri ortadan kaldırmak diyebiliriz.

Yukarıda örnek olarak oluşturduğumuz koşul senaryomuz için ilk etapda components.xml dosyasında tagları arasında  filtremizi tanımlamamız gerekiyor.

<persistence:filter name="CUSTOMER_FILTER" enabled="#{identity.loggedIn}">
	<persistence:name>CUSTOMER_FILTER</persistence:name>
	<persistence:parameters>
		<key>customer_id</key>
		<value>#{current.id}</value>
	</persistence:parameters>
</persistence:filter>



Yukarıdaki kodları incelediğimiz zaman öncelikle fiterımıza bir isim veriyoruz. Daha sora bu filter'ın hibernate sorgularında ne zaman aktif olacağını belirtiyoruz. Müşteri oturum açtıktan itibaren filteremiz aktif olacak diyoruz.  customer_id alanına parametre olarak ise session katmanında bulunan customer nesnesinin id değişkenini atıyoruz. Bu tanımlamadan sonra component.xml dosyasında tanımlanmış olan managed-persistence-context konfigürasyonuna filterımızı eklememiz gerekiyor.

<persistence:managed-persistence-context
	name="entityManager" auto-create="true"
	persistence-unit-jndi-name="java:/maqasEntityManagerFactory">
	<persistence:filters>
		<value>#{CUSTOMER_FILTER}</value>
	</persistence:filters>
</persistence:managed-persistence-context>



components.xml ile ilgili tanımlamalar bu kadar.  net.maqas.project.entity şeklinde bir paket yapımız olsun. Bu paket altında entity sınıflarımız yer alıyor. Bu pakete package-info.java isminde yeni bir dosya ekleyelim. Bu java dosyası içinde filterlarımız ile ilgili hibernate tanımlamalarını yapacağız.

 
@FilterDefs( {
	@FilterDef(name = "CUSTOMER_FILTER", defaultCondition = "(CUSTOMER_ID =:customer_id) ", parameters = @ParamDef(name = "customer_id", type = "integer"))
})
package net.maqas.project.entity

import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterDefs;
import org.hibernate.annotations.ParamDef;

package-info.java dosyamızın içeriği yukarıdaki gibi olacak. Burada gerekli hibernate annotationları ilgili tanımlamarı bir kez olmak üzere paket üzerinde global olarak tanımlıyoruz.  

Filter ile ilgili tanımlama package-info.java dosyası ile sona eriyor. Artık bu filter'i kullanacak entity üzerine gene annotation yardımı ile eklemek kalıyor. Örnek bir entity sınıfı oluşturalım.

@Entity
@Table(name = "CUSTOMER_ANNOUNCEMENT")
@Filters({
	@Filter(name="CUSTOMER_FILTER")
})
public class Announcement Serializable {

	private Integer id;
	private String subject;
	private String message;
	private Customer customer;
	
	
	//...
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "CUSTOMER_ID", nullable = false)
	public Customer getCustomer() {
		return customer;
	}
	
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
	//...

}

Müşterilere ait duyuruları tutan Announcement isminde bir entity ekledik ve Customer entity'si ile aralarinda MantyToOne iliski oldugunu isaretledik ve CUSTOMER_ID ile birbirine bagladik. Burada dikkat edeceginiz nokta entity sinifimizin üzerine @Filters annotationi ile Customer filtirimizi eklememiz. Bundan sonra Announcement entity üzerinden yapilacak hibernate sorgularina otomatik olarak customer_id kriter olarak eklenecektir.

Kamil Örs
Software Developer 






0.000181198120117 | 3.5