Ρύθμιση βάσης δεδομένων και JPA

PostgreSQL

Το Heroku παρέχει τη βάση δεδομένων PostgreSQL. Δημιουργήσαμε μια βάση δεδομένων στο Heroku εδώ. Θα δημιουργήσουμε τους πίνακες στη τοπική βάση δεδομένων. Μετά, μπορούμε να κάνουμε export τη βάση και να την κανουμε import στον απομακρυσμένο server στο Heroku.

Για να μπορέσουμε, να χρησιμοποιήσουμε τις βάσεις, χρειάζεται να προσθέσουμε κάποια dependencies στο pom.xml, να προσθέσουμε κάποια properties στο αρχείο application.properties και να δημιουργήσουμε μια κλάση configuration, για να ρυθμίσουμε το JPA.

Dependencies

Προσθέτουμε στο αρχείο pom.xml, τα ακόλουθα dependencies.

                    
                            <dependency>
                                <groupId> org.springframework.boot </groupId>
                                <artifactId< spring-boot-starter-data-jpa </artifactId>
                            </dependency>

                            <dependency>
                                <groupId> org.postgresql </groupId>
                                <artifactId> postgresql </artifactId>
                            </dependency>
                    
                

Application Properties

Προσθέτουμε τα ακόλουθα properties στο αρχείο application.properties. Τα πρώτα 8 περιέχουν ρυθμίσεις για την τοπική και απομακρυσμένη βάση δεδομένων, όπως URL, username και password. Όταν θέλουμε, να τρέξουμε την εφαρμογή τοπικά, πρέπει να κάνουμε comment out τα properties για το Heroku. Αντίστοιχα όταν θέλουμε, να κάνουμε push τις αλλαγές μας στο Heroku, πρέπει να κάνουμε comment out τα properties για το local. Επίσης, παρέχουμε κάποια properties που χρειάζεται το Hibernate και το HikariCP.

                
                            #local
                            spring.datasource.driver-class-name = org.postgresql.Driver
                            spring.datasource.url = jdbc:postgresql://localhost:5432/postgres
                            spring.datasource.username = postgres
                            spring.datasource.password = root 

                            #Heroku
                            spring.datasource.driver-class-name = org.postgresql.Driver
                            spring.datasource.url = ${JDBC_DATABASE_URL}
                            spring.datasource.username = ${JDBC_DATABASE_USERNAME}
                            spring.datasource.password = ${JDBC_DATABASE_PASSWORD}

                            spring.jpa.properties.hibernate.hbm2ddl.method = update
                            spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
                            spring.jpa.properties.hibernate.show_sql = true
                            spring.jpa.properties.hibernate.format_sql = true
                            spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

                            spring.datasource.hikari.minimumIdle=2
                            spring.datasource.hikari.maximumPoolSize=10
                            spring.datasource.hikari.idleTimeout=300000
                            spring.datasource.hikari.maxLifetime=1200000
                            spring.datasource.hikari.connectionTimeout=20000
                
            
Δημιουργία κλάσης JpaConfiguration

Θα δημιουργήσουμε μια κλάση JpaConfiguration.java, η οποία θα περιέχει διάφορες ρυθμίσεις για το JPA. Πρώτα, θα κάνουμε ένα καινούριο package springeshop.configuration στο project μας. Στο Spring Tool Suite, πατάμε SpringEshop -> src/main/java, κάνουμε δεξί κλικ -> New -> Package και δίνουμε το όνομα springeshop.configuration . Στο πακέτο αυτό κάνουμε δεξί κλικ -> New -> Class, δίνουμε το όνομα JpaConfiguration και πατάμε finish.

Προσθέτουμε τα ακόλουθα annotations :

@Configuration : Η κλάση περιέχει bean definitions, δηλαδή beans με το annotation @Bean
@EnableJpaRepositories : Είναι annotation, για να ενεργοποιηθούν τα JpaRepositories.
@EnableTransactionManagement : Είναι annotation, για να ενεργοποιηθεί το transaction management.

                    
                            package springeshop.configuration;

                            @Configuration
                            @EnableJpaRepositories(basePackages = "springeshop.repositories",
                                          entityManagerFactoryRef = "entityManagerFactory",
                                          transactionManagerRef = "transactionManager")
                            @EnableTransactionManagement
                            public class  JpaConfiguration {
                    
                
Datasource Bean

Το Datasource Bean είναι ένα εργοστάσιο για τη δημιουργία συνδέσεων με το φυσικό datasource, το οποίο αυτό Datasource αντικειμένο αναπαριστά, δηλαδή την βάση δεδομένων PostgreSQL. Χρειάζεται, να δώσουμε τιμές σε παραμέτρους, όπως το url της βάσης, το username, password και το Jdbc Driver, τις οποίες παίρνουμε από το αρχείο application.properties .

                    

                            @Autowired
                            private Environment environment(){

                            @Bean(name = "dataSource"
                            public DataSource dataSource(){
                              DriverManagerDataSource dataSource = new DriverManagerDataSource();
		                      dataSource.setDriverClassName(environment.getProperty("spring.datasource.driver-class-name"));
		                      dataSource.setUrl(environment.getProperty("spring.datasource.url"));
		                      dataSource.setUsername(environment.getProperty("spring.datasource.username"));
	                          dataSource.setPassword(environment.getProperty("spring.datasource.password"));	
                              return dataSource;
                            }
                    
                

Transaction Manager Bean

Πρέπει να δημιουργήσουμε ένα transaction manager bean, το οποίο ενσωματώνει τον JPA provider, με το transaction management του Spring. Θα χρησιμοποιήσουμε την κλάση JpaTransactionManager, ως τον transaction manager της εφαρμογής.

                    
                            @Bean
                            @Autowired
	                        public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
                              JpaTransactionManager txManager = new JpaTransactionManager();
                              txManager.setEntityManagerFactory(emf);
                              return txManager;
                            }
                    
                

JpaVendorAdapter Bean

Δηλώνουμε ότι θα χρησιμοποιήσουμε το Hibernate ως persistence provider

                    
                            @Bean
                            public JpaVendorAdapter jpaVendorAdapter(){
                                HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
                                return hibernateJpaVendorAdapter;
                            }
                    
                

JpaProperties

Δηλώνουμε κάποια συγκεκριμένα properties για το Hibernate.

                    
                            private Properties jpaProperties(){
                                Properties properties = new Properties();	
                                properties.put("hibernate.hbm2ddl.method", environment.getRequiredProperty("spring.jpa.properties.hibernate.hbm2ddl.method"));
                                properties.put("hibernate.show_sql", environment.getRequiredProperty("spring.jpa.properties.hibernate.show_sql"));
                                properties.put("hibernate.format_sql", environment.getRequiredProperty("spring.jpa.properties.hibernate.format_sql"));
                                properties.put("hibernate.dialect", environment.getRequiredProperty("spring.jpa.properties.hibernate.dialect"));
                                properties.put("hibernate.jdbc.lob.non_contextual_creation", environment.getRequiredProperty("spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation"));
                            return properties;
                        }
                    
                

EntityManager Bean

Για να χρησιμοποιήσουμε το JPA, πρέπει να δημιουργήσουμε τον EntityManager. Ο EntityManager παρέχει λειτουργίες πάνω στη βάση, όπως η εύρεση και η αποθήκευση αντικειμένων.

                    
                            @Bean
                            public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
                              LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
                              factoryBean.setDataSource(dataSource());
                              factoryBean.setPackagesToScan(new String[] { "springeshop.model" });
                              factoryBean.setJpaVendorAdapter(jpaVendorAdapter());
                              factoryBean.setJpaProperties(jpaProperties());
                            return factoryBean;