Blogg

Här finns tekniska artiklar, presentationer och nyheter om arkitektur och systemutveckling. Håll dig uppdaterad, följ oss på Twitter

Callista medarbetare Jan Västernäs

Spring Data JPA Projections

// Jan Västernäs

Jag älskar spring framework! Redan 2005 bjöd vi in upphovsmannen Rod Johnson till ett CallistaEvent i Göteborg. Han hade året innan skrivit sin genombrottsbok “J2EE Development without EJB”. I början handlade det mycket om att vara ett alternativ till Java EE:s komponentmodell, Rod och Spring var lite rebeller mot etablissemanget och det var ganska kul. Han höll ett antal presentationer för oss under en eftermiddag och tog sedan Ryanair hem till London igen.

Sedan dess har vi använt spring framework i de flesta av våra projekt och ramverket har ju utvecklats till att bli väldigt omfattande kan man väl säga :-)

En väldigt positiv sak tycker jag är all den dokumentation som finns att läsa. Hade nyligen problem med en applikation som bygger på spring boot 2. Det var prestandaproblem vid sökning mot en composit. Den består av närmare 10 tabeller och innehåller ganska mycket FetchType=EAGER vilket innebar att det exekverades en heltäckningsmatta av sql-satser med massa joins för varje träff (sammanlagt c:a 1000 st i detta fall) vilket tog c:a 15 sekunder att utföra vilket inte var acceptabelt. Dvs JPA ville ladda in alla tabeller trots att jag bara var intresserad av 5 attribut i rot-tabellen. Eager load fungerar bra i mer transaktionsorienterade sammanhang vid bearbetning av enstaka objekt så det var inte aktuellt att ändra på det.

Koden före ändring

    public interface OrderRepository extends CrudRepository<Order, Long> {
		 
	    List<Order> findByHsaId(@Param("hsaId") String hsaId);
	
    }

Som genererade

Fick i stället tips av en kollega om Spring Data JPA Projektions. Med hjälp av en länk till ett utmärkt material från baeldung så gjorde jag en minimalistisk ändring i Repository-interfacet för composit-roten. I stället för att returnera instanser av Order-objektet (med alla sina barn) skapade jag ett interface OrderView som innehåll metoder för att hämta de fem aktuella attributen. De skall ha samma namn som i original-domänobjektet Order.

Kod efter ändring

    public interface OrderRepository extends CrudRepository<Order, Long> {
		 
	    List<OrderView> findByHsaId(@Param("hsaId") String hsaId);
	
    }

    public interface OrderView {
	
	    long getId();
	    OrderType getOrderType();
	    String getComponentDescription(); 
	    OrderState getStatus();
	    LocalDateTime getCreated();

    }

Och då genereras bara en enda sql-sats

Det här är väl inte varken helt nytt eller revolutionerande, men det visar tycker jag på hur bra det brukar fungera att använda olika features i spring på detaljnivå. När jag fattat exemplet tog det c:a 15 minuter att införa och testa - fungerade exakt som förväntat från första försöket. Ibland blir man lycklig :-)

Tack för att du läser Callistas blogg.
Hjälp oss att nå ut med information genom att dela nyheter och artiklar i ditt nätverk.

Kommentarer