Il sito dedicato all'informatica ideato da Iasparra Francesco

Spring Data JPA

  • Utilizzare Spring Data JPA con le Java Annotation, incredibile cosa si riesce a fare.

  • Data: 04/10/2014 Autore: Iasparra Francesco 

Non voglio con questo articolo scendere troppo nel tecnico ma vedere cosa si riesce a fare con due righe di codice utilizzando JPA con Spring con delle semplici Java Annotation che il framework mette a disposizione.

JPA di Spring permette di avere transazioni senza nessuna particolare configurazione.

Con le Java Annotation introdotte nelle ultime versioni dei progetti di Spring e' possibile configurare l'intero ambiente senza dover scrivere nessun file xml di configurazione.

Questo porta enormi vantaggi, in primo luogo non bisogna scrivere codice e poi ricordarsi di referenziarlo eventualemente nel file xml di configurazione, ma e' possibilie utilizzare semplici annotazioni, inoltre qualunque riferimento o configurazione scritta male quindi errata viene immeriatamente rilevata in fase di scrittura di codice, cosa che invece scrivendo un file xml non avviene, ma e' necessario avviare l'applicazione prima di rilevare un errore di scrittura.

Supponiamo di avere la seguente configurazione del Data Source:

package test.springmvc.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.beans.PropertyVetoException;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("test.springmvc.repository")
@PropertySource("classpath:datasource.properties")
public class DBConfig
    extends WebMvcConfigurerAdapter {

    @Autowired
    private Environment env;

    @Bean
    public DataSource dataSource() {
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(env.getRequiredProperty("jdbc.driverclassname"));
            ds.setJdbcUrl(env.getRequiredProperty("jdbc.url"));
            ds.setUser(env.getRequiredProperty("jdbc.username"));
            ds.setPassword(env.getRequiredProperty("jdbc.password"));
            ds.setMaxStatements(50);
            ds.setMaxPoolSize(100);
            ds.setMinPoolSize(10);
            ds.setAcquireIncrement(5);
            ds.setPreferredTestQuery("SELECT 1;");
            ds.setIdleConnectionTestPeriod(60);
            //ds.setTestConnectionOnCheckin(true);
            //ds.setMaxIdleTimeExcessConnections(240);
            return ds;
        } catch (IllegalStateException e) {
            throw new RuntimeException(e);
        } catch (PropertyVetoException e) {
            throw new RuntimeException(e);
        }
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource);
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("test.beans");

        // Defines the Hibernate properties
        Properties jpaProperties = new Properties();
        //jpaProperties.setProperty("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
        //jpaProperties.setProperty("hibernate.format_sql", env.getRequiredProperty("hibernate.format_sql"));
        //jpaProperties.setProperty("hibernate.hbm2ddl.auto", env.getRequiredProperty("hibernate.hbm2ddl.auto"));
        //jpaProperties.setProperty("hibernate.hbm2ddl.import_files", env.getRequiredProperty("hibernate.hbm2ddl.import_files"));
        //jpaProperties.setProperty("hibernate.hbm2ddl.import_files_sql_extractor", "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor");

        lef.setJpaProperties(jpaProperties);

        return lef;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
        //hibernateJpaVendorAdapter.setShowSql(false);
        //hibernateJpaVendorAdapter.setGenerateDdl(true);
        hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
        return hibernateJpaVendorAdapter;
    }

    @Bean
    public PlatformTransactionManager transactionManager(
        EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

A questo punto definiamo lo JpaRepository:

package test.springmvc.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import test.beans.User;

public interface UserRepository extends JpaRepository<User, Long>{    
    public User findByUsername(String username); 
    
    @Query("SELECT u FROM User u WHERE u.username=:username")
    public User getUser(String username);
}

La funzione findByUsername viene convertita da JapRepository automaticamente in una query che ricerca per username, questo e' un automatismo molto potente e permette di scrivere query sql senza scrivere una riga di codice sql.

Inoltre e' possibile costruire query ah-hoc dichiarandole attraverso l'annotazione @Query.

Supponiamo ora di fare una semplice interrogazione e verificare se esiste lo username admin:

package test.springmvc.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import test.beans.User;
import test.springmvc.repository.UserRepository;

@Service
public class HomeService {
    
    @Autowired
    private UserRepository userRepository;
    
    public User caricaUtente(){
        User result=null;
        result=userRepository.findByUsername("admin");
        return result;
    }
}    

Utilizzando la funzione findByUsername (quindi la prima definita in UserRepository) cerchiamo ed otteniamo il bean User.


  • Java

  • Php

  • Mysql

  • Apache ant

  • Eclipse

  • Spring

  • Hibernate

  • Netbeans

  • Debian

  • Linux

  • Maven