Εμφάνιση αναρτήσεων με ετικέτα JdbcTemplate. Εμφάνιση όλων των αναρτήσεων
Εμφάνιση αναρτήσεων με ετικέτα JdbcTemplate. Εμφάνιση όλων των αναρτήσεων

Πέμπτη 21 Οκτωβρίου 2021

Spring Certification: Spring Boot Auto Configuration

How does Spring Boot know what to configure?
  • These classes contain ConditionalOn.. classes that scan classpath resources and register beans, according to starters and dependencies that user introduced in POMs
  • Spring Boot checks for the presence of a META-INF/spring.factories file within your published jar. The file should list your configuration classes under the EnableAutoConfiguration key, as shown in the following example:
    • org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      com.code.in.packets.autoconf.SomeAutoConfiguration1,\
      com.code.in.packets.autoconf.SomeAutoConfiguration2
  • See all ConditionalOn classes
  • Using @Profile("some-profile") on a @Bean, and then load this profile

  • Using @Conditional("<some-class>") on a @Bean




What does @EnableAutoConfiguration do?

  • Applied in Application/Main class of Spring application
  • In Spring Boot application, already included in @SpringBootApplication annotation
  • Responsible for kick-starting autoconfiguration process, by
    • @AutoConfigurationPackage
      • Importing AutoConfigurationPackages.Registrar, that registers a bean which provides Bean list for Spring boot to use internally, in spring-boot-autoconfigure package
    • @Import(EnableAutoConfigurationImportSelector.class)
      • Imports AutoConfigurationImportSelector that aggregates all spring.factories
  • Can exclude some autoconfiguration class, like: @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) in our @Configuration class



What does @SpringBootApplication do?

  • Applied only in root package class, and contains below annotations:
  • @EnableAutoConfiguration: enables Spring Boot’s auto-configuration mechanism
  • @ComponentScan: enable @Component scan on the package where the application is located
  • @Configuration: allow to register extra beans in the context or import additional configuration classes

Does Spring Boot do component scanning? Where does it look by default?
  • Yes, @ComponentScan or @SpringBootApplication enables component scanning.
  • By default, it scans for components in whole package (and subpackages) of the class with @SpringBootApplication
  • If no component scanning is set, it only scans the package of the main class
  • @ComponentScan is also used to specify base packages and base package classes using thebasePackageClasses or basePackages attributes


How are DataSource and JdbcTemplate auto-configured?
  • DataSource 
    •  with DataSourceAutoConfiguration class from spring-boot-autoconfigure package.
    • that retrieves properties spring.datasource.url, spring.datasource.username, spring.datasource.password from application.properties or yml file.
  • JdbcTemplate
    • with JdbcTemplateAutoConfiguration, that contains:
    • @ConditionalOnClass(value={javax.sql.DataSource.class,org.springframework.jdbc.core.JdbcTemplate.class})
      • If DataSource class exists in classpath, only then configure JdbcTemplate
    • @ConditionalOnSingleCandidate(value=javax.sql.DataSource.class)
      • We need only one candidate
    • @AutoConfigureAfter(value=DataSourceAutoConfiguration.class) 
      • First configure DataSource, and only then JdbcTemplate 

What is spring.factories file for?
  • spring.factories contains auto-configuration classes needed for the AutoConfiguration mechanism of Spring
  • @EnableAutoConfiguration eventually gathers all spring.factories files of all project modules/packages and aggregates them into one.
  • A spring.factories contains an EnableAutoConfiguration key with values as the list of auto-configuration classes, and resides under META/INF directory
  • spring.factories should be used when we want to set default components globally for our app. Thus the need for @Autowire-ing a dependency disappears. But of course, this default behavior can later be overwritten with some @Bean/@Configuration


How do you customize Spring Boot auto configuration?
  • To create our own auto-configuration: 
    • add a spring.factories in META-INF, with content:
    • org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.myapp.package1.autoconfigure.MyDataSourceAutoConfiguration, com.myapp.package2.autoconfigure.MyJpaAutoConfiguration
    • Implement above classes as @Configurations accordingly to specific needs
    • Disable loading of auto-configuration class for DataSource loading:  @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) 


What are the examples of @Conditional annotations? How are they used?

Conditional classes are used from within AutoConfiguration classes to load conditionally classpath resources :
  • ConditionalOnBean - Spring Bean must be registered
  • ConditionalOnMissingBean - Spring Bean must not be registered
  • ConditionalOnClass - Class must exist in classpath
  • ConditionalOnMissingClass - Class must not exist in classpath
  • ConditionalOnExpression - spEL expression must result to true
  • ConditionalOnJava - Java JDK in certain version must exist
  • ConditionalOnJndi - JNDI location should exist
  • ConditionalOnProperty - property must exist
  • ConditionalOnResource - resource must exist

Δευτέρα 4 Οκτωβρίου 2021

Spring Certification: Data Management, JDBC, Transactions

What is the difference between checked and unchecked exceptions?

  • Checked exceptions are evaluated (checked) in compile time
  • Unchecked exceptions are evaluated in runtime

  • Checked exceptions are all under Throwable (except Error and RuntimeException)
  • Unchecked exceptions are all under Error and RuntimeException

  • Use checked exceptions if it's possible to recover from the exception and continue program flow
  • Unchecked exceptions are not meant to be caught (produced from unforeseen programming errors)


Why does Spring prefer unchecked exceptions?
  • Adding checked exceptions introduces boilerplate code and extra dependencies, in contrast with Spring's principle to decouple dependencies from caller code (Spring IoC/DI)
  • Testing becomes more difficult
  • Disrupts S.O.L.I.D principles of Spring, by introducing high coupling


What is Spring data access Exception Hierarchy?
  • Spring isolates/abstracts DB vendor-specific exceptions (e.g. exceptions from JDBC/JPA/Hibernate implementations) and incorporates them in its own hierarchy
  • Root class: DataAccessException, Main branches: NonTransientDataAccessException, RecoverableDataAccessException, TransientDataAccessException
  • Examples: BadSqlGrammarException, DuplicateKeyException, EmptyResultDataAccessException, CannotGetJdbcConnectionException, QueryTimeoutException
  • Access Exception Hierarchy using xxx-Template classes, e.g. JDBCTemplate


How do you configure a DataSource in Spring?
  • Using Spring beans that use a JDBC driver
    • SimpleDriverDataSource, DriverManagerDataSource (creates new connection per request, multi-threading ability)
    • SingleConnectionDataSource (does not close connection after use, not multi-thread capable)
  • Using JNDI data source bean
    • JndiObjectFactoryBean
    • Database external to the application
    • Pooled datasources, greater performance, hot-swapping 
  • Using pooled datasources
    • Spring does not provide by default
    • Use Apache Commons DBCP,  BasicDatasource
  • Using embedded data source bean
    • EmbeddedDatabaseBuilder
    • Testing purposes


What is the Template design pattern and what is the JDBC template?

  • Template design pattern defines a base class with fixed implementations regarding common functionalities (fixed part), and delegates implementation regarding specific needs (variable part) to subclasses, using callbacks
  • JdbcTemplate defines connection init/close, transaction handling, clean up / releases in fixed part, and enforces implementations regarding handling result set, binding params, creating statements, in variable part.



What is a callback? What are the JdbcTemplate callback interfaces that can be used with queries? What is each used for?

  • A callback is a function that is to be executed after another function has finished executing
  • In Spring's JdbcTemplate, callbacks are used to handle a ResultSet after a query execution, and more

  • Callback interfaces:
    • RowCallbackHandler: handles each row of a ResultSet and can choose not to return the domain object, but to store it somewhere else
    • RowMapper<T>: each row of ResultSet is mapped to domain object
    • ResultSetExtractor<T>: multiple rows of ResultSet are mapped in one object
    • PreparedStatementCreator: creates a prepared statement given a Connection provided by this class, providing SQL and any necessary parameters.  


Can you execute a plain SQL statement with the JDBC template?

  • Yes, using:
  • execute()
    • Use for DDL statements
  • query()
    • Provides variety for query results handling/mapping, using ResultSetExtractor, RowMapper, RowCallbackHandler
  • queryForList()
    • Use when we want query results for one column only (one or many rows)
  • queryForObject()
    • Use when we expect one row result
  • queryForMap()
    • Use when we expect one row result. Returns a map with [column + value]
  • queryForRowSet()
    • Use if column metadata are needed
  • update()
    • Updates, using a PreparedStatementSetter or PreparedStatementCreator
  • batchUpdate()


When does the JDBC template acquire (and release) a connection, for every method called or once per template? Why?

  • For every method called. query() and update() use execute() which acquires connection from connection pool. (if such one exists)
  • Reason is to keep connection resource open only for as long as it's needed

How does the JdbcTemplate support queries? How does it return objects and lists/maps of objects?

  • queryForObject: use when one row result is expected. Optional: call queryForObject with a callback parameter, in case of mapping result to domain object
  • queryForList: use when multiple expected row results, with each containing only one column information
  • queryForMap: use when single row is expected. Returns map of column names as keys and column values as values   
  • queryForRowSet: Returns a SqlRowSet object that contains column metadata and is iterable


What is a transaction? What is the difference between a local and a global transaction?
  • The context of execution for a group of SQL operations is called a transaction. All sql should run successfully or all should revert if any produces failure. Transaction embodies the ACID principle:
    • Atomicity (all, or none)
    • Consistency (cant save book-1 orders if no book-1 exists)
    • Isolation (no other concurrent transaction should interfere in our transaction)
    • Durability (assurance that our data are stored safely, e.g. across many DB systems)
  • Local transactions: Application has one database to associate all transactions, usually with a JDBC connection
  • Global transactions: Application spans across many databases, and a distributed DB management is applied, maybe through Java Transaction API (JTA)


Is a transaction a cross cutting concern? How is it implemented by Spring
  • Yes it is
  • A bean postprocessor of type InfrastructureAdvisorAutoProxyCreator acts on @Service and @Repository beans and creates proxies for @Transactional methods wrapping latter in an Around advice, first for initiating connections, and after for closing them.
  • These proxies use TransactionInterceptor infrastructure bean and an implementation of PlatformTransactionManager (e.g. HibernateTransactionManager)


How are you going to define a transaction in Spring?
  • Declaratively: 
    • @Configuration class with @EnableTransactionManagement
    • Use @Transactional in method
  • Programmatically:
    • Use TransactionTemplate with a callback having our transaction logic
    • Use PlatformTransactionManager along with TransactionDefinition and TransactionStatus
    

Is the JDBC template able to participate in an existing transaction?
  • Yes, by wrapping a Datasource in a proxy of type TransactionAwareDataSourceProxy, and using first to instantiate the JDBC Template 
  • Example:
    • DataSource ds = new TransactionAwareDataSourceProxy(datasource);
      JdbcTemplate template = new JdbcTemplate(ds);


What is a transaction isolation level? How many do we have and how are they ordered?
  • A level that is set per transaction, and refers to the degree of communication with other transactions operating on same data set
  • There are 4 isolation levels, ordered as:
    • READ_UNCOMMITTED
      • Allows dirty reads (not yet committed), non-repeatable reads (reads that if repeated, may show altered row data) and phantom reads (reads that if repeated, may show same row data, but also more new rows)
    • READ_COMMITTED
      • Allows non-repeatable reads and phantom reads
      • Doesn't allow dirty reads
    • REPEATABLE_READ
      • Allows  phantom reads
      • Doesn't allow dirty and non-repeatable reads
    • SERIALIZABLE
      • Allows none

Example:

Consider two transactions, T1 and T2, are both dealing with a BankAccount entity with id=1:

  • READ UNCOMMITTED: T1 starts and updates the balance. T2 reads the balance while T1 is still running. T2 sees the uncommitted changes of T1.

  • READ COMMITTED: T1 starts and updates the balance. T2 tries to read the balance before T1 commits. T2 will only see the committed balance, not the changes made by T1 until T1 is committed.

  • REPEATABLE READ: T1 reads balance first. Meanwhile, T2 changes the balance and commits. If T1 reads the balance again, it will see the same value as the first read, even if T2 has committed a change.

  • SERIALIZABLE: Both T1 and T2 cannot run in parallel on the same User entity (id=1). They will be executed one after another, ensuring complete isolation.



What is @EnableTransactionManagement for?
  • Enables transaction support in Spring
  • Added in a @Configuration class
  • Either registers a bean called txManager or PlatformTransactionManager by type, that developer provided with @Bean
  • Defines a bean post-processor, that will act on @Service classes, looking for @Transactional method, to add proxy:
    • Registers TransactionInterceptor
    • Registers a JDK proxy

  • In Spring Boot, it's not needed since spring-boot-starter-data-jpa dependency and a Datasource are declared.
How does transaction propagation work?
  • Example: @Transactional(propagation=Propagation.REQUIRED) 
  • REQUIRES_NEW:  always create a new transaction (suspend existing, if any)
  • NOT_SUPPORTED:  execute without transaction support, (suspend existing, if any)
  • NEVER: execute without transaction support, (exception, if any exists)
  • REQUIRED: use existing transaction (create new, if none exists)
  • SUPPORTS: use existing transaction if any, else run non-transactionally
  • MANDATORY: if none already exists, throw exception
  • NESTED: if any exists, run extra nested transaction in it, else create a whole new one

What happens if one @Transactional annotated method is calling another @Transactional annotated method inside a same object instance?
  • No extra proxy is created and no extra transaction
  • Explanation: First, when a Bean @Transactional method is called, a proxy bean is created. Then, if our Bean calls itself (some other method), there is no need for an extra proxy bean. Transactions comply only with current PROPAGATED enums, and no new/extra is created.

Where can the @Transactional annotation be used? What is a typical usage if you put it at class level?
  • On class and method level
  • Class level: define a default behavior (can alter specifically for each method with @Transactional)
  • Class level: applies for all subclasses
  • Method level: needs to be public

What does declarative transaction management mean?
  • Enable Spring transaction support with annotations, like @EnableTransactionManagement
    • which enables a txManager/PlatformTransactionManager bean
  • and @Transactional
    • which enables proxy to handle the transaction basic jobs, like initiating/closing connection, and in-between execute our logic     
What is the default rollback policy? How can you override it?
  • Transaction is rollbacked when any runtime exception occurs, by default
  • Override with: rollbackForClassName, noRollbackFor, noRollbackForClassName
  • Example 1: @Transactional(noRollbackFor=SomeCheckedOrUncheckedException.class)
  • Example 2: @Transactional(rollbackForClassName="SomeCheckedOrUncheckedException"})

What is the default rollback policy in a JUnit test, when you use the @RunWith(SpringJUnit4ClassRunner.class) in JUnit 4 or @ExtendWith(SpringExtension.class) in JUnit 5, and annotate your @Test annotated method with @Transactional?

  • By default, every test method will execute inside a transaction, and will rollback after completion
  • Alter with @Commit on class/method level, and @Rollback(false) on method level

Are you able to participate in a given transaction in Spring while working with JPA?
  • Yes, within one @Transactional, already configured JpaTransactionManager (from Spring JPA) provides a transaction context on which we can interfere with e.g. JDBCTemplate / lower lever sql functions.


Which PlatformTransactionManager(s) can you use with JPA?
  •  JpaTransactionManager 
    • Serves one transaction context per resource
  •  JtaTransactionManager
    • Servers one transaction context across multiple resources

What do you have to configure to use JPA with Spring? How does Spring Boot make this easier?
  • JPA with plain Spring:
    • @Entities and CrudRepositories per entity
    • @Configuration class with
      • @EnableTransactionManagement
      • PlatformTransactionManager bean
      • LocalContainerEntityManagerFactoryBean / EntityManager
      • DataSource bean

  • JPA with Spring boot
    •  spring-boot-starter-data-jpa and all needed transitive dependencies
    • Auto-configuration for JPA (PlatformTransactionManager, EntityManager, .. )
    • Can configure datasource in properties file
    • Support for Hikari connection pool

Τετάρτη 28 Απριλίου 2021

Spring Boot @DataJpaTest with simple @Repository stereotype and JdbcTemplate



Spring Boot @DataJpaTest with simple @Repository stereotype







1. DAO implementation with JdbcTemplate

@Repository public class UspNeighboursDAOImpl implements UspNeighboursDAO { @Autowired private JdbcTemplate jdbcTemplate; final String SELECT_QUERY = "select * from usp_neighbours where usp_id = ?"; @Override public List<Map<String, Object>> getNeighboursByUspId(int uspId) { return jdbcTemplate.queryForList(SELECT_QUERY, uspId); } } // DAO Interface public interface UspNeighboursDAO { List<Map<String, Object>> getNeighboursByUspId(int uspId); }


2. Testing

@DataJpaTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class ApplicationTests { @Autowired private UspNeighboursDAO uspNeighboursDAO; @Test public void testNeighbours1() { List<?> resList = uspNeighboursDAO.getNeighboursByUspId(2); assertEquals(resList.size(), 2); } }