Spring Exception Translation nasıl çalışır?

Gökhan Birinci
Kod Gemisi
Published in
2 min readApr 2, 2018

Geliştirdiğiniz uygulamaların birçoğu bir şekilde veritabanına ihtiyaç duyuyor. Bu nedenle bir O/R teknolojisine ihtiyacınız olabilir. Kullandığınız O/R teknolojileri runtimeda çeşitli exceptionlar fırlatabilir, bu yüzden persistence teknolojisinin exceptionlarının nasıl ele alınacağının kararını vermek zorundasınız. Bu nedenlerle exceptionlara göre dizayn ettiğiniz service layerınız sizi kullandığınız bu teknolojiye bağımlı yapıyor, dolayısıyla coupling artıyor. Spring bize tam da bu noktada güzel bir özellik sağlıyor. Spring implicit olarak, o specific exceptionlardan daha üst seviyede, onları wrap eden ortak exceptionlar yaratıyor; böylelikle O/R değişse bile, siz service layerınızı güncellemek zorunda kalmıyorsunuz.

Gelin beraber detaylı bir şekilde inceleyelim.

Diyelim ki projeye Hibernate kullanarak başladınız ve service layerınızı da Hibernate specific exceptionlara göre dizayn ettiniz, fakat birkaç ay sonra yeni bir kararla farklı bir teknolojiye geçiş kararı alındı. Bu karardan sonra zaten DAOlarınızı değiştirmek zorunda kalacaksınız. Service layerınızda Hibernate-specific bir dizayna sahip olduğu için service katmanınızı da değiştirmek zorunda kalacaksınız. Bu istemeyeceğimiz bir şey.

Bu konuda Spring, desteklediği O/R araçlarının exception hiyerarşilerinin üzerine oturttuğu bir exception hiyerarşisi sağlar. Spring, desteklediği herhangi bir O/R aracının fırlattığı database exceptionını ya da errorunu kendi hiyerarşisinde karşılık gelen exception/error’ a çevirerek yakalar(Spring Exception Translation). Bu da service layerınızı persitence teknolojinizden bağımsız bir şekilde dizayn etmenize olanak sağlar.

Spring Exception hiyerarşisi org.springframework.dao.DataAccessException ın bir alt sınıfı olarak tanımlanır. Spring kullanılan persistence teknolojisinin fırlattığı herhangi bir hatayı yakalar ve DataAccessException instance’ı ile sarmalar(wraps it).DataAccessException objesi bir “unchecked” exceptiondır çünkü RuntimeExceptionı extend eder, bu yüzden declare ya da catch etmenize gerek yoktur.

Bununla birlikte, Spring, @Repository anotasyonu ile exception translation’ ı etkinleştirir. Buradan @Repository anotasyonunu inceleyebilirsiniz.

Gelin Spring için bu anlattıklarımıza örnek bir uygulama implement edelim.

Employee diye bir entitymiz olsun ve içinde id, name ve surname fieldları olsun:

… bu entity için içinde addEmployee(Employee employee) metodu olan ve HibernateException fırlatan bir DAO oluşturalım:

Şimdi bu DAO için servisimizi oluşturalım.

Şimdi normal şartlarda eğer EmployeeDao sınıfını @Repository ile annotate etmeseydik addEmployee metodumuz çalışacak ve:

testimiz başarılı olacaktı ama şu anda Stack Trace baktığımızda:

java.lang.Exception: Unexpected exception, expected<org.hibernate.HibernateException> but was<org.springframework.orm.jpa.JpaSystemException>

hatasını görüyoruz; yani Spring exceptionı wrap ederek kendi hiyerarşisinde bir mapleme yapmış ve “org.springframework.orm.jpa.JpaSystemException” fırlatmış.

Eğer expected değerini DataAccessException yaparsak testimiz başarıyla gerçekleşecektir.

Kaynak Kodu:
https://github.com/gokhanbirincii/blog-projects/tree/master/springexceptiontranslation

Kaynaklar:
https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#orm-exception-translation
Spring Persistence with Hibernate : A. Reza Seddighi

--

--