Spring Study Guide – Data Integration

1. What is the difference between checked and unchecked exceptions?

A checked exception is an exception that is caught during compile time. Usually, if you use an IDE, the IDE will show you that you have a checked exception.

An unchecked exception is an exception that is caught at runtime. It is not caught during compile time. You have to account for this type of exception and provide a way to handle it at runtime.

  • Checked exceptions: Java compiler requires to handle. E.g., Exception
  • Unchecked exceptions: compiler not require to declare. E.g., RuntimeException.

2. Why does Spring prefer unchecked exceptions?

  • Checked exceptions reqires handling, result in cluttered code and unnecessary coupling.
  • Unchecked exceptions are non-recoverable exceptions, should not let developer to handle. E.g., when SQLException happens, nothing you can do.

Spring prefers unchecked exception because this way it gives the developer possibility to choose to handle them or not –  he is not enforced to handle them. To use Spring specific exceptions you must use Spring templates. JdbcTemplate takes care of transforming SQLExceptions to meaningful DataAccessExceptions, this is done using SQLExceptionTranslators.

3. What is the data access exception hierarchy?

Each data access technology has its own exception types, such as

  • SQLException for direct JDBC access,
  • HibernateException used by native Hibernate, or
  • EntityException used by JPA

What Spring does is to handle technology‐specific exceptions and translate them into its own exception hierarchy. The hierarchy is to isolate developers from the particulars of JDBC data access APIs from different vendors.

Spring’s DataAccessException

  • It is an abstract class,
  • It is the root exception.
  • Its sub-classes are unchecked exceptions.

Spring data access exception family has three main branches:

  1. org.springframework.dao.NonTransientDataAccessException
    • non-transient exceptions,
    • which means that retrying the operation will fail unless the originating cause is fixed.
    • The most obvious example here is searching for an object that does not exist.
  2. RecoverableDataAccessException
    • when a previously failed operation might succeed if some recovery steps are performed,
    • usually closing the current connection and using a new one.
    • E.g., a temporary network hiccup
  3. springframework.dao.TransientDataAccessException.
    • transient exception,
    • which means that retrying the operation might succeed without any intervention.
    • These are concurrency or latency exceptions.
    • For example, when the database becomes unavailable because of a bad network connection in the middle of the execution of a query, an exception of type QueryTimeoutException is thrown. The developer can treat this exception by retrying the query.

4. How do you configure a DataSource in Spring? Which bean is very useful for development/test databases?

DataSource is a generalized connection factory. It hides connection pooling and transaction management from application code. Spring obtains connections to a database through a DataSource.

With Spring you can configure different types of DataSources:

  • JDBC-driver defined DataSources
  • JNDI DataSources
  • Connection-pooling DataSources 

JDBC driver-based DataSources are the simples type. Spring has 3 types of them:

  1. DriverManagerDataSource
  2. SimpleDriverDataSource
  3. SingleConnectionDataSource
@Bean
public DataSource datasource(){
   DriverManagerDataSource ds = new DriverManagerDataSource();
   ds.setDriverClassName("org.h2.Driver"); //this is a in-memory DB
   ds.setUrl("jdbc:h2:tcp://localhost/~/databaseName");
   ds.setUsername("admin");
   ds.setPassword("pass");
   return ds;
}

A very important DataSource implementation for development/testing purposes is the embedded data source. H2 is an embedded data source that is mostly used by developers for testing.

 

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

The Template method design pattern is about the following: you have an abstract class that has one final non-abstract method that defines some algorithm and more abstract methods that are to be implemented in the child classes. And when you run the final method (that you get from the abstract class) you get the algorithm defined in the abstract class but the implementation is done in the child non-abstract class. Meanwhile, our JdbcAccessor class that is abstract and is the parent class for JdbcTemplate has no such a method that is final and defines some algorithm.

JdbcTemplate is a convenience class that hides a lot of JDBC boilerplate code and allows to:

  • execute SQL queries
  • execute update statement
  • performs stored procedures calls
  • iterates over ResultSets
  • extracts returned parameter values

The Spring JdbcTemplate simplifies the use of JDBC by implementing common workflows for

  1. querying,
  2. updating,
  3. statement execution etc.

Benefits are:

  • Simplification: reduces boilerplate code for operations
  • Handle exceptions
  • Translates Exception from different vendors, e.g., DataAccessException
  • Avoids common mistake: release connections
  • Allows customization, it’s template design pattern
  • Thread safe

Spring comes with three template classes to choose from:

  1. JdbcTemplate
  2. NamedParameterJdbcTemplate
  3. SimpleJdbcTemplate (deprecated)

JdbcTemplate:

  • JdbcTemplate works with queries that specify parameters using the '?' placeholder.

  • Use queryForObject when it is expected that execution of the query will return a single result.

  • Use RowMapper<T> when each row of the ResultSet maps to a domain object.

  • Use RowCallbackHandler when no value should be returned.

  • Use ResultSetExtractor<T> when multiple rows in the ResultSet map to a single object.

  • initialize JdbcTemplate

    The general practice is to initialize JdbcTemplate within the setDataSource method so that once the data source is injected by Spring, JdbcTemplate will also be initialized and ready for use.

    Once configured, JdbcTemplate is thread-safe. That means you can also choose to initialize a single instance of JdbcTemplate in Spring’s configuration and have it injected into all DAO beans.

 @Configuration
  public class DemoJdbcConfig {
    @Bean
    public DataSource dataSource() {
      return new DataSource();
    }

    @Bean
    public JdbcTemplate jdbcTemplate(){
      JdbcTemplate jdbcTemplate = new JdbcTemplate();
      jdbcTemplate.setDataSource(dataSource());
      return jdbcTemplate; 
    }
}

NamedParameterJdbcTemplate:

The NamedParameterJdbcTemplate class adds support for programming JDBC statements by using named parameters, as opposed to programming JDBC statements using only classic placeholder ( '?' ) arguments.

public int countOfActorsByFirstName(String firstName) {

  String sql = "select count(*) from T_ACTOR where first_name = :first_name";
  SqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);
  return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}

//Map-based style
public int countOfActorsByFirstName(String firstName) {

  String sql = "select count(*) from T_ACTOR where first_name = :first_name";
  Map<String, String> namedParameters = Collections.singletonMap("first_name", firstName);
  return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}

// BeanPropertySqlParameterSource
public int countOfActors(Actor exampleActor) {

  String sql = "select count(*) from T_ACTOR where first_name = :firstName and last_name = :lastName";
  
  SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(exampleActor);
  
  return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class); 
}

 

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

callback is any executable code that is passed as an argument to other code, which is expected to call back(execute) the argument at a given time

public class Test {
    public static void main(String[] args) throws  Exception {
        new Test().doWork(new Callback() { // implementing class            
            @Override
            public void call() {
                System.out.println("callback called");
            }
        });
    }

    public void doWork(Callback callback) {
        System.out.println("doing work");
        callback.call();
    }

    public interface Callback {
        void call();
    }
}

JdbcTemplate 3 central callback interfaces:

  • RowCallbackHandler – An interface used by JdbcTemplate for processing rows of a ResultSet on a per-row basis
  • CallableStatementCreator – One of the three central callback interfaces used by the JdbcTemplate class. This interface creates a CallableStatement given a connection, provided by the JdbcTemplate class.
  • PreparedStatementCreator – One of the two central callback interfaces used by the JdbcTemplate class. This interface creates a PreparedStatement given a connection, provided by the JdbcTemplate class.

Others:

  • ResultSetExtractor
  • BatchPreparedStatementSetter – Batch update callback interface used by the JdbcTemplate class. This interface sets values on a PreparedStatement provided by the JdbcTemplate class
  • ParameterizedPreparedStatementSetter – Parameterized callback interface used by the JdbcTemplate class for batch updates. This interface sets values on a PreparedStatement provided by the JdbcTemplate class.
  • PreparedStatementCallback – Generic callback interface for code that operates on a PreparedStatement
  • StatementCallback – Generic callback interface for code that operates on a JDBC Statement
  • CallableStatementCallback – Generic callback interface for code that operates on a CallableStatement
  • ResultSetExtractor – Callback interface used by JdbcTemplate’s query methods.
  • PreparedStatementSetter – General callback interface used by the JdbcTemplate class. This interface sets values on a PreparedStatement provided by the JdbcTemplate class.

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

Yes, using execute() methods – one of them accepts StatementCallback objects and the other wraps the String you pass in a StatementCallback. StatementCallback in its turn has a doInStatement() method that accepts Statement objects. So you can pass either an anonymous class with overridden doInStatement() method or just a simple String that execute() method of Statement will be run on.

template.execute(new StatementCallback<ResultSet>() {
    public ResultSet doInStatement(Statement statement) throws SQLException, DataAccessException {
        ResultSet rs = statement.executeQuery("SELECT * FROM databaseTable");
        RowCallbackHandler handler = new RowCallbackHandler() {
            public void processRow(ResultSet resultSet) throws SQLException {
                while (resultSet.next()) {
                    System.out.println(resultSet.getObject(1) + "," + resultSet.getObject(3));
                }
            }
        };
        handler.processRow(rs);
        return rs;
    }
});

Yes. With following methods:

  • batchUpdate()
  • execute()
  • query()
  • queryForList()
  • queryForObject()
  • queryForRowSet()
  • update()

DML
DML stands for Data Manipulation Language, the commands SELECT, INSERT, UPDATE, and DELETE are database statements used to create, update, or delete data from existing tables.

DDL DDL stands for Data Definition Language, used to manipulate database objects: tables, views, cursors, etc. DDL database statements can be executed with JdbcTemplate using the execute method.

public int createTable(String name) {

  jdbcTemplate.execute("create table " + name + " (id integer, name varchar2)" );

  String sql = "select count(*) from " + name;

  return jdbcTemplate.queryForObject(sql, Integer.class);
}

 

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

It DOES NOT acquire connection per template. It acquire connection per method and release it after that method.

If you take a look at The execute() method :

  • picks up Connection object from connection pool / create connection.
  • create Statment object.
  • execute sql query.
  • release Connection object.

Method’s like updatequeryForObject internally call execute()

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

JdbcTemplate supports querying for any type of object

It has many overloaded methods for querying the database but mainly you can divide them in:

  1. query()
  2. queryForObject() – if you are expecting only one object
  3. queryForMap() – will return a map containing each column value as key(column name)/value(value itself) pairs.
  4. queryForList() – a list of above if you’re expecting more results 
  • objects – queryForObject – SingleColumnRowMapper for generic types and RowMapper for custom types
  • lists – queryForList – SingleColumnRowMapper for generic types
  • maps – queryForMap – ColumnMapRowMapper for any query

10. 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. Run them all successfully, or reverted. Tansaction enforces ACID principle.

Transactions are described in terms of ACID properties, which are as follows:

  • Atomicity: All changes to data are performed as if they are a single operation. That is, all the changes are persisted, or none of them are. For example, in an application that transfers funds from one account to another, the atomicity property ensures that, if a debit is made successfully from one account, the corresponding credit is made to the other account.
  • Consistency: Data is in a consistent state when a transaction starts and when it ends. For example, in an application that transfers funds from one account to another, the consistency property ensures that the total value of funds in both the accounts is the same at the start and end of each transaction.
  • Isolatation: The intermediate state of a transaction is invisible to other transactions. As a result, transactions that run concurrently appear to be serialized. For example, in an application that transfers funds from one account to another, the isolation property ensures that another transaction sees the transferred funds in one account or the other, but not in both, nor in neither.
  • Durability: After a transaction successfully completes, changes to data persist and are not undone, even in the event of a system failure. For example, in an application that transfers funds from one account to another, the durability property ensures that the changes made to each account will not be reversed.

In short a local transaction is a simple transaction that is about one single database; whilst a global one is application server managed and spreads across many components/ technologies. For global transactions consider the case that a record must be persisted in a database ONLY if some message is sent to a queue and processed – if the later fail the transaction must be rolled back.

11. Is a transaction a cross-cutting concern? How is it implemented by Spring?

Yes as it can affect many components. The core concept in Spring transactions world is the transaction strategy that is defined by PlatformTransactionManager. This interface is a service provider interface. It has multiple implementations and the one you choose depends on your requirements. From PlatformTransactionManager through getTransaction() method – by passing the TransactionDefinition in, you get the TransactionStatus that may represent a new or an existing transaction.

TransactionStatus specifies:

  • isolation
  • propagation
  • propagation 
  • read-only status 

of the transaction to be looked up in the PlatformTransactionManager.

12. How are you going to define a transaction in Spring?

Two ways of implementing it:

  1. Declarative, use @transaction
  2. Programmatic
    • Use TransactionTemplate
    • Use PlatformTransactionManager

Declarative transaction management

Declarative transaction management is non-invasive.

  1. Configure transaction management support
    • Marked a Spring Configuration class using the @Configuration
    • Using Java Configuration, define a PlatformTransactionManager bean using @bean
    • Enable transaction management by annotate the config file with @EnableTransactionManagement
    • @Configuration
       @EnableTransactionManagement
       public class TestDataConfig {
         @Bean
         public PlatformTransactionManager txManager(){
           return new DataSourceTransactionManager(dataSource());
         }
       }
  2. Declare transactional methods using @Transactional
    @Service
    public class UserServiceImpl implements UserService {
      @Transactional(propagation = Propagation.REQUIRED, readOnly= true)
      @Override
      public User findById(Long id) {
        return userRepo.findById(id);
      }
    }

    Programmatic transaction management

    It is possible to use both declarative and programmatic transaction models simultaneously.

    Programmatic transaction management allows you to control transactions through your codeexplicitly starting, committing, and joining them as you see fit.

    Spring Framework provides two ways of implemeting Programmatic Transaction:

    1. Using TransactionTemplate, which is recommended by Spring;
    2. Using PlatformTransactionManager directly, which is low level.

    Using TransactionTemplate It uses a callback approach.
    can write a TransactionCallback implementation, run execute(..)

    public class SimpleService implements Service {
    
       // single TransactionTemplate shared amongst all methods in this instance
       private final TransactionTemplate transactionTemplate;
    
       // use constructor-injection to supply the PlatformTransactionManager
       public SimpleService(PlatformTransactionManager transactionManager) {
         this.transactionTemplate = new TransactionTemplate(transactionManager);
       }
    
       public Object someServiceMethod() {
    
         return transactionTemplate.execute(new TransactionCallback() {
           // the code in this method executes in a transactional context
           public Object doInTransaction(TransactionStatus status) {
             updateOperation1();
             return resultOfUpdateOperation2();
           }
         });
       }
     }

Declarative way deals with adding some AOP related to transactions to the methods annotated with @Transactional or that have some tx-advices defined by XML.

Programmatic way is about using either TransactionTemplate or directly PlatformTransactionManager.

13. What does @Transactional do? What is the PlatformTransactionManager?

General Rule: Add the @Transaction annotation to the method that start (and finish) the unit of work. That is the part of your program that should been handled in on transaction (meaning, that it should be done/saved completely or not at all).

Rather than using XML AOP for matching the methods that should be transactional you can add this (@Transactional) annotation. PlatformTransactionManager is an interface that defines the transaction strategy through different implementations that match requirements specific to the project they are used in.

@Transactional is metadata that specifies that an interfaceclass, or method must have transactional semantics.

@Transactional Settings

  1. The transactionManager attribute value defines the transaction manager used to manage the transaction in the context of which the annotated method is executed

  2. The readOnly attribute should be used for transactions that involve operations that do not modify the database (example: searching, counting records). Defalt FALSE.

  3. The propagation attribute can be used to define behavior of the target methods: if they should be executed in an existing or new transaction, or no transaction at all. There are seven propagation types. Default: PROPAGATION_REQUIRED.

  4. The isolation attribute value defines how data modified in a transaction affects other simultaneous transactions. As a general idea, transactions should be isolated. A transaction should not be able to access changes from another uncommitted transaction. There are four levels of isolation, but every database management system supports them differently. In Spring, there are five isolation values. DEFAULT: the default isolation level of the DBMS.

  5. timeout. By default, the value of this attribute is defined by the transaction manager provider, but it can be changed by setting a different value in the annotation: @Transactional(timeout=3600) by milliseconds.

  6. rollbackFor. When this type of exception is thrown during the execution of a transactional method, the transaction is rolled back. By default, i’s rolled back only when a RuntimeException or Errors is thrown. In using this attribute, the rollback can be triggered for checked exceptions as well.

  7. noRollbackFor attribute values should be one or more exception classes, subclasses of Throwable. When this type of exception is thrown during the execution of a transactional method, the transaction is not rolled back. By default, a transaction is rolled back only when a RuntimeException is thrown. Using this attribute, rollback of a transaction can be avoided for a RuntimeException as well.

Default settings for @Transactional:

  • Propagation setting is PROPAGATION_REQUIRED.
  • Isolation level is ISOLATION_DEFAULT.
  • Transaction is read/write, which is read only = FALSE.
  • Transaction timeout defaults to the default timeout of the underlying transaction system, or to none if timeouts are not supported.
  • Any RuntimeException triggers rollback, and any checked Exception does not.

Annotation driven transaction settings:

  • mode
    • The default mode (proxy) processes annotated beans to be proxied by using Spring’s AOP framework.
    • The alternative mode (aspectj) instead weaves the affected classes with Spring’s AspectJ transaction aspect, modifying the target class byte code to apply to any kind of method call. AspectJ weaving requires spring-aspects.jar in the classpath as well as having load-time weaving (or compiletime weaving) enabled.
  • proxyTargetClas
    • Applies to proxy mode only.
    • If it’s false or omitted, then standard JDK interface-based proxies are created.
    • If the proxy-target-class attribute is set to true, class-based proxies are created.
  • order
    • Defines the order of the transaction advice that is applied to beans annotated with @Transactional
    • Default Ordered.LOWEST_PRECEDE NCE.

14. Is the JDBC template able to participate in an existing transaction?

If you define a method as @Transactional and internally add some JdbcTemplate code it will run in that transaction; but JdbcTemplate itself cannot manage transactions – that is job of TransactionTemplate.

15. What is a transaction isolation level? How many do we have and how are they ordered?

Transaction isolation level is the level of one isolation of one transaction from another. Transaction level is defined from the perspective of 3 characteristics:

  1. Dirty reads – one transaction can read uncommitted data from other transaction
  2. Non-repeatable read – occurs when a second transaction reads the same row from the first transaction at different times getting different data each time because of the first transaction committing some changes or deleting the row.
  3. Phantom reads – occurs when the same search criteria is returning different data because of some other transaction interfering and deleting/adding data.

In Spring we have the following isolation levels:

  • int ISOLATION_DEFAULT = -1 – Use the default isolation level of the underlying datastore.
  • int ISOLATION_READ_UNCOMMITTED = 1 – Indicates that dirty reads, non-repeatable reads, and phantom reads can occur.
  • int ISOLATION_READ_COMMITTED = 2 – Indicates that dirty reads are prevented; non-repeatable reads and phantom reads can occur.
  • int ISOLATION_REPEATABLE_READ = 4 – Indicates that dirty reads and non-repeatable reads are prevented; phantom reads can occur.
  • int ISOLATION_SERIALIZABLE = 8 – Indicates that dirty reads, non-repeatable reads, and phantom reads are prevented.

16. What is @EnableTransactionManagement for?

The @EnableTransactionManagement annotation to be used in on @Configuration classes and enable transactional support:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{
 
   @Bean
   public LocalContainerEntityManagerFactoryBean
     entityManagerFactoryBean(){
      //...
   }
 
   @Bean
   public PlatformTransactionManager transactionManager(){
      JpaTransactionManager transactionManager
        = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(
        entityManagerFactoryBean().getObject() );
      return transactionManager;
   }
}

Both @EnableTransactionManagement and <tx:annotation-driven ../> enable all infrastructure beans necessary for supporting transactional execution.

Components registered when the @EnableTransactionManagement annotation is used are:

  • A TransactionInterceptor: calls to @Transactional methods
  • A JDK Proxy or AspectJ advice, intercepts methods annotated with @Transactional

@EnableTransactionManagement and <tx:annotation-driven/> only looks for @Transactional on beans in the same application context they are defined in. This means that, if you put annotation driven configuration in a WebApplicationContext for a DispatcherServlet it only checks for @Transactional beans in your controllers, and not your services.

17. What does transaction propagation mean?

Transaction propagation defines whether the current transaction will be extended or not.

There is an Enum that specifies the list of all possible propagation types – org.springframework.transaction.annotation.Propagation:

REQUIRES_NEW  create a new transaction, suspend any existing one
MANDATORY use current transaction, throw exception if none exists
REQUIRED use current transaction, if non exists – create one
SUPPORTS use current transaction, execute non-transactionally if none exists
NEVER execute non-transactionally, throw exception if any transaction exists
NOT_SUPPORTED execute non-transactionally, suspend any existing transaction
NESTED if a transaction exists create a nested one in it and execute everything there, else behave like Propagation.REQUIRED

It is to define behavior of the target methods: if they should be executed in an existing or new transaction, or no transaction at all.

Spring Propagation enum:

  1. Propagation.REQUIRED@Transactional(propagation = Propagation.REQUIRED)
    • Starts a new transaction if there is no transaction.
    • An existing transaction is kept and the second method call is executed within the same transaction.
    • If the second method throws an exception that causes rollback, the whole transaction rolls back. It doesn’t matter if the first transaction handles that exception or not.
    • Transaction rolls back and throws UnexpectedRollbackException.
  2. Propagation.REQUIRES_NEW:
    • always starts a new transaction regardless of whether there is already an active one.
  3. Propagation.NESTED.
    • there is only one active transaction that spans method calls.
    • only available if your persistence technology is JDBC.
    • it won’t work if you are using JPA or Hibernate.
    • JDBC savepoints are used to mark new method calls. When an exception occurs in the second method, the transaction until the last savepoint is rolled back
  4. Propagation.MANDATORY.
    • An error occurs if there is not an active transaction.
  5. Propagation.NEVER.
    • An error occurs if there is an active transaction in the system when the method is called.
  6. Propagation.NOT_SUPPORTED:
    • If there is an active transaction when the method is called, the active transaction is suspended until the end of the method call.
  7. Propagation.SUPPORTS.
    • current method work in a transaction if one already exists.
    • Otherwise, the method will work without any transaction.
@Service
public class UserServiceImpl implements UserService {
  
  @Transactional(propagation = Propagation.REQUIRED, readOnly= true)
  @Override public User findById(Long id) {
  return userRepo.findById(id);
  }
}

 

18. What happens if one @Transactional annotated method is calling another @Transactional annotated method on the same object instance?

Since transaction-management is implemented using AOP @Transactional annotation will have no effect on the method being called as no proxy is created. The same behavior is characteristic of AOP aspects.

As per the limitation of Spring AOP, a self-invocation of a proxied Spring Bean effectively bypasses the proxy, thus the second method will be excuted in the same transaction with the first.

Service layer or Repository layer

Use @Transactional in the service layer or the DAO/ repository layer, but not both.

The service layer is the usual choice, because service methods call multiple repository methods that need to be executed in the same transaction.

The only reason to make your repositories transactional is if you do not need a service layer at all, which is usually the case for small educational applications.

19. Where can the @Transactional annotation be used? What is a typical usage if you put it at the class level?

If you put @Transactional at class-level this is equal to annotating each method of that class.

Class level:

  1. default for all methods of the declaring class
  2. method level transactional can override some attributes
  3. its subclasses
  4. does not apply to ancestor classes up the class hierarchy

Method level:

  1. Only Public method
  2. protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the congured transactional settings.
  3. If you need to annotate non-public methods, consider using AspectJ

Interface:

  1. this works only as you would expect it to if you use interface-based proxies
  2. recommends that you annotate only concrete classes and methods

20. What does declarative transaction management mean?

For declarative transaction management:

  1. It keeps transaction management out of business logic.
  2. Easy to configure. Use Java annotations or XML configuration files.

Basically, when those specified methods are called, Spring begins a new transaction, and when the method returns without any exception it commits the transaction; otherwise, it rolls back. Hence, you don’t have to write a single line of transaction demarcation code in your method bodies.

How It Works:

  1. The @EnableTransactionManagement annotation activates annotation‐based declarative transaction management.

  1. Spring Container scans managed beans’ classes for the @Transactional annotation.

  2. When the annotation is found, it creates a proxy that wraps your actual bean instance.

  3. From now on, that proxy instance becomes your bean, and it’s delivered from Spring Container when requested.

Programmatic transaction management is a good idea only if:

  1. Has only a small number of transactional operations. For example, if you have a web application that requires transactions only for certain update operations, you may not want to set up transactional proxies by using Spring or any other technology.
  2. Being able to set the transaction name explicitly.

21. What is the default rollback policy? How can you override it?

Any RuntimeException (unchecked exception) or Error will cause by default a rollback. Checked exceptions don’t cause a rollback

How to rollback?

Just throw any RuntimeException from a method marked as @Transactional. By default all RuntimeExceptions rollback transaction whereas checked exceptions don’t.

How to override default rollback?

You can configure this by using rollbackFor and noRollbackFor annotation parameters:

@Transactional(rollbackFor=Exception.class)

The above example will rollback transaction after throwing any exception.

@Transactional too has some parameters for changing the default behaviour:

  • rollbackFor
  • noRollbackFor
  • rollbackForClassName
  • noRollbackForClassName

Rollback without exception:

You can call the following code inside your method annotated with @Transactional

22. 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?

Test transactions will be automatically rolled back after completion of the test.

You need to annotate test method with @Transnational for transaction.

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?

  • Test-methods will be executed in a transaction, and will roll back after completion.
  • The rollback policy of a test can be changed using the @Rollback set to false, @Rollback(false)
  • @Commit indicates that the transaction for a transactional test method should be committed after the test method has completed. You can use @Commit as a direct replacement for @Rollback(false) to more explicitly convey the intent of the code. Analogous to @Rollback, @Commit can also be declared as a class-level or method-level annotation.

The @DataJpaTest tests are transactional and rolled back at the end of each test by default. You can disable this default rollback behavior for a single test or for an entire test class by annotating with @Transactional(propagation = Propagation.NOT_SUPPORTED).


23. Why is the term “unit of work” so important and why does JDBC AutoCommit violate this pattern?

JDBC AutoCommit will treat each individual SQL statement as a transaction. This means that if logically or from business point of view you need to make sure some statement is OK before executing another one, it would fail. Transactions are meant to solve this problem by “grouping” operations in some logical way so that you confirm to ACID principle (Atomicity, Consistency, Isolation, Durability). 

  • The unit of work describes the atomicity of transactions.
  • JDBC AutoCommit will cause each individual SQL statement as to be executed in its own transaction, which makes it impossible to perform operations that consist of multiple SQL statements as a unit of work.
  • JDBC AutoCommit can be disabled by calling the setAutoCommit() to false on a JDBC connection.


24. What does JPA stand for – what about ORM?

JPA stands for Java Persistent API. ORM stands for Object Relational Mapping.

JPA: Java Persistence API. JPA is a POJO-based persistence mechanism that draws ideas from both Hibernate and Java Data Objects (JDO) and mixes Java 5 annotations in for good measure.

ORM: Object-Relational Mapping. Mappingg a java entity to SQL database table.

Benefits of using Spring’s JPA support in your data access layer:

  • Easier and more powerful persistence unit configuration
  • Automatic EntityManager management
  • Easier testing
  • Common data access exceptions
  • Integrated transaction management

The first step toward using JPA with Spring is to configure an entity manager factory as a bean in the Spring application context. JPA-based applications use an implementation of EntityManagerFactory to get an instance of an EntityManager. The JPA specification defines two kinds of entity managers:

Application-managed

  • the application is responsible for opening or closing entity managers and involving the entity manager in transactions.
  • most appropriate for use in standalone applications that don’t run in a Java EE container.
  • EntityManagers are created by an EntityManagerFactory obtained by calling the createEntityManagerFactory() method of the PersistenceProvider.
  • If you’re using an application-managed entity manager, Spring plays the role of an application and transparently deals with the EntityManager on your behalf.
  • LocalEntityManagerFactoryBean produces an application-managed EntityManagerFactory.
  • Application-managed entity-manager factories derive most of their configuration information from a configuration file called persistence.xml. This file must appear in the META-INF directory in the classpath. The purpose of the persistence.xml file is to define one or more persistence units.
@Bean
 public LocalEntityManagerFactoryBean entityManagerFactoryBean() {

   LocalEntityManagerFactoryBean emfb = new LocalEntityManagerFactoryBean();
   emfb.setPersistenceUnitName("demo");
   return emfb;
 }

Container-managed

  • Entity managers are created and managed by a Java EE container.
  • The application doesn’t interact with the entity manager factory at all.
  • Instead, entity managers are obtained directly through injection or from JNDI.
  • The container is responsible for configuring the entity manager factories.
  • most appropriate for use by a Java EE container that wants to maintain some control over JPA configuration beyond what’s specified in persistence.xml.
  • EntityManagerFactorys are obtained through PersistenceProvider’s createContainerEntityManagerFactory() method.
  • Spring plays the role of the container.
  • LocalContainerEntityManagerFactoryBean produces a container-managed EntityManagerFactory.
  • Instead of configuring data-source details in persistence.xml, you can configure this information in the Spring application context.
  • JPA has two annotations to obtain container‐managed EntityManagerFactory or EntityManager instances within Java EE environments.
    1. The @PersistenceUnit annotation expresses a dependency on an EntityManagerFactory, and
    2. @PersistenceContext expresses a dependency on a containermanaged EntityManager instance.
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory( DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
  LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
  emfb.setDataSource(dataSource);
  emfb.setJpaVendorAdapter(jpaVendorAdapter);
  return emfb;
}

 

25. What is the idea behind an ORM? What are the benefits/disadvantages or ORM?

ORM is to help map our domain or entity models into database tables. In the application level, we deal with objects and not with database operations.

Idea: Developers only work on objects and no need to care about how to maintain the relationship and how they persist.

ORM Duties:

  • Data type convertion
  • Maintaining relations between objects
  • JAP Query language to handle vendor spedific SQL

Benefits:

  • Easier testing. It’s easier to test each piece of persistence-related code in isolation.
  • Common data access exceptions. In DataAccessException hierarchy.
  • General resource management. Spring offers effcient, easy, and safe handling of persistence resources. E.g., Spring makes it easy to create and bind a Session to the current thread transparently, by exposing a current Session through the Hibernate SessionFactory .
  • Integrated transaction management. Declarative, aspect-oriented programming (AOP) style method interceptor.
  • Keep track of changes
  • Reduce code (and develop time)
  • Lazy loading. As object graphs become more complex, you sometimes don’t want to fetch entire relationships immediately.
  • Eager fetching. Eager fetching allows you to grab an entire object graph in one query.
  • Cascading. Sometimes changes to a database table should result in changes to other tables as well
  • Save you literally thousands of lines of code and hours of development time.
  • Lets you switch your focus from writing error-prone SQL code to addressing your application’s requirements.

Disadvantage:

  • Generated SQL Query low performance
  • Complexity, requires more knowledge
  • Deal with legacy database is difficult

26. What is a PersistenceContext and what is an EntityManager? What is the relationship between both?

JPA has two annotations to obtain container‐managed EntityManagerFactory or EntityManager instances within Java EE environments.

  1. The @PersistenceUnit annotation expresses a dependency on an EntityManagerFactory, and
  2. @PersistenceContext expresses a dependency on a containermanaged EntityManager instance.

@PersistenceUnit and @PersistenceContext

  • They aren’t Spring annotations; they’re provided by the JPA specification.
  • Both annotations can be used at either the field or method level.
  • Visibility of those fields and methods doesn’t matter.
  • Spring’s PersistenceAnnotationBeanPostProcessor must be configured explicitly:

  • @Bean
     public PersistenceAnnotationBeanPostProcessor paPostProcessor() {
       return new PersistenceAnnotationBeanPostProcessor();
     }
  • if you do use Spring’s exception translation

    @Bean
      public BeanPostProcessor persistenceTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
      }

    @PersistenceContext

    • Used for entity manager injection.
    • Expresses a dependency on a container-managed EntityManager and its associated persistence context.
    • This field does not need to be autowired, since this annotation is picked up by an infrastructure Spring bean postprocessor bean that makes sure to create and inject an EntityManager instance.
    • @PersistenceContext has a type attribute
      • PersistenceContextType.TRANSACTION In stateless beans, like singleton bean, it is safe to use only the PersistenceContextType.TRANSACTION value for a shared EntityManager to be created and injected into for the current active
      • PersistenceContextType.EXTENDED
        • is purposefully designed to support beans, like stateful EJBs, session Spring beans, or request‐scoped Spring beans. The shared EntityManager instance wouldn’t be bound to the active transaction and might span more than one transaction.

    PersistenceContext It’s essentially a Cache, containing a set of domain objects/entities in which for every persistent entity there is a unique entity instance.

    • Default persistence context duration is one single transaction
    • Can be configured
    • the persistence context itself is managed by EntityManager

    Persistence Unit:
    a group of entity classes defined by the developer to map database records to objects that are managed by an Entity Manager, basically all classes annotated with @Entity, @MappedSuperclass, and @Embedded in an application.

    • All entity classes must define a primary key, must have a non-arg constructor or not allowed to be final.
    • This set of entity classes represents data contained in a single datasource.
    • Multiple persistence units can be defined within the same application.
    • Configuration of persistence units can be done using XML, e.g., persistence.xml file under the META-INF directory. JPA no need to specify it.

    EntityManager represents a PersistenceContext. The entity manager provides an API for managing a persistence context and interacting with the entities in the persistence context.

    • It does creation, update, querying, deletion.
    • An EntityManager isn’t thread-safe and generally shouldn’t be injected into a shared singleton bean like your repository. @PersistenceContext doesn’t inject an EntityManager—at least, not exactly. Instead of giving the repository a real EntityManager, it gives a proxy to a real EntityManager. That real EntityManager either is one associated with the current transaction or, if one doesn’t exist, creates a new one.

    EntityManagerFactory
    It has the responsibility of creating application-managed Entity Manager instances and therefore a PersistenceContext/Cache. Thread safe, shareable, represent a single datasource and persistence context.

    @Repository
    public class JpaUserRepo implements UserRepo {
      private EntityManager entityManager;
      
      @PersistenceContext
      void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
      }
    }

     

27. Why do you need the @Entity annotation? Where can it be placed?

 

28. What do you need to do in Spring if you would like to work with JPA?

  1. Declare dependencies: ORM dependency, db driver dependency, transaction manager dependency.

  2. @Entity classes
    • is part of the javax.persistence.*, not JPA!
    • @Entity marks classes as templates for domain objects, also called entities to database tables.
    • The @Entity annotation can be applied only at class level.
    • @Entity are mapped to database tables matching the class name, unless specified otherwise using the@Table annotation.
    • @Entity and @Id are mandatory for a domain class.
  3. Define an EntityManagerFactory bean.
    • Simplest: LocalEntityManagerFactoryBean. It produces an application-managed EntityManagerFactory.
    • Obtain an EntityManagerFactory using JNDI, use when app ran in Java EE server
    • Full JPA capabilities: LocalContainerEntityManagerFactoryBean
  4. Define a DataSource bean

  5. Define a TransactionManager bean

  6. Implement repositories
@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
class ApplicationConfig {

  @Bean
  public DataSource dataSource() {
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    return builder.setType(EmbeddedDatabaseType.HSQL).build();
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.acme.domain");
    factory.setDataSource(dataSource());
    return factory;
  }
@Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory);
    return txManager;
  }
}

You must create LocalContainerEntityManagerFactoryBean and not EntityManagerFactory directly, since the former also participates in exception translation mechanisms in addition to creating EntityManagerFactory .

29. Are you able to participate in a given transaction in Spring while working with JPA?

Yes you can.

The Spring JpaTransactionManager supports direct DataSource access within one and the same transaction allowing for mixing plain JDBC code that is unaware of JPA with code that use JPA.

If the Spring application is to be deployed to a JavaEE server, then JtaTransactionManager can be used in the Spring application.

30. Which PlatformTransactionManager(s) can you use with JPA?

Implementations of PlatformTransactionManager interface. E.g.,

  1. DataSourceTransactionManager: Suitable if you are only using JDBC

  2. HibernateTransactionManager
    • Hibernate without JPA
    • Also possible to use JDBC at the same time
  3. JpaTransactionManager:
    • Suitable if you are using JPA.
    • Also possible to use JDBC at the same time
  4. JdoTransactionManage
    • using JDO
    • Also possible to use JDBC at the same time
  5. JtaTransactionManager
    • Suitable if you are using global transactions—that is, the distributed transaction management capability of your application server.
    • You can use any data access technology
  6. WebLogicJtaTransactionManager

JtaTransactionManager is used for global transactions, so that they can span multiple resources such as databases, queues etc. If the application has multiple JPA entity manager factories that are to be transactional, then a JTA transaction manager is required.

When using JPA with one single entity manager factory, the Spring Framework JpaTransactionManager is the recommended choice. This is also the only transaction manager that is JPA entity manager factory aware.

31. What does @PersistenceContext do?

@PersistenceContext

  • Used for entity manager injection.
  • Expresses a dependency on a container-managed EntityManager and its associated persistence context.
  • This field does not need to be autowired, since this annotation is picked up by an infrastructure Spring bean postprocessor bean that makes sure to create and inject an EntityManager instance.
  • @PersistenceContext has a type attribute
    • PersistenceContextType.TRANSACTION In stateless beans, like singleton bean, it is safe to use only the PersistenceContextType.TRANSACTION value for a shared EntityManager to be created and injected into for the current active
    • PersistenceContextType.EXTENDED
      • is purposefully designed to support beans, like stateful EJBs, session Spring beans, or request‐scoped Spring beans. The shared EntityManager instance wouldn’t be bound to the active transaction and might span more than one transaction.

PersistenceContext It’s essentially a Cache, containing a set of domain objects/entities in which for every persistent entity there is a unique entity instance.

  • Default persistence context duration is one single transaction
  • Can be configured
  • the persistence context itself is managed by EntityManager

32. What do you have to configure to use JPA with Spring? How does Spring Boot make this easier?

To use Spring Data components in a JPA project, a dependency on the package spring-data-jpa must be introduced.

JPA in SpringBoot

  1. SpringBoot provides a default set fo dependencies needed for JPA in starter.
  2. Provides all default Spring beans needed to use JPA.
  3. Provides a number of default properties related to persistence and JPA.

Disable Spring Data Auto Configuration in SpringBoot:

It’s useful in testing.

  1. Disable Using Annotation

    @SpringBootApplication(exclude = {
      DataSourceAutoConfiguration.class,
      DataSourceTransactionManagerAutoConfiguration.class,
      HibernateJpaAutoConfiguration.class})

     

  2. Disable Using Property File

    spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,
    org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,
    org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration

     

33. What is an “instant repository”? (hint: recall Spring Data)

Spring Data repository is also known as a “instant” repository, because they can be created instantly by extending one of the Spring-specialized interfaces.

When a custom repository interface extends JpaRepository, it will automatically be enriched with functionality to save entities, search them by ID, retrieve all of them from the database, delete entities, flush, etc.

By default, repositories are instantiated eagerly unless explicitly annotated with @Lazy. LAZY is a decent choice for testing scenarios.

34. How do you define an “instant” repository? Why is it an interface not a class?

Under the hood, Spring creates a proxy object that is a fullly functioning repository bean. The repository implementation is generated at application startup time, as the Spring application context is being created.

Any additional functionality that is not provided by default can be easily implemented by defining a method skeleton and providing the desired functionality using annotations. It’s including an implementation of all 18 methods inherited from

  • JpaRepository,
  • PagingAndSortingRepository, and
  • CrudRepository.

JDBC Support typical JDBC support. You could have the DataSource injected into an initialization method, where you would create a JdbcTemplate and other data access support classes

@Repository
public class JdbcMovieFinder implements MovieFinder {

  private JdbcTemplate jdbcTemplate;

  @Autowired
  public void init(DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(dataSource);
  }
}

JPA repository JPA-based repository needs access to an EntityManager.

@Repository
public class JpaMovieFinder implements MovieFinder {
  
  @PersistenceContext
  private EntityManager entityManager;
}

classic Hibernate APIs inject SessionFactory

@Repository
public class HibernateMovieFinder implements MovieFinder {

  private SessionFactory sessionFactory;

  @Autowired
  public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
  }
}

 

35. What is the naming convention for finder methods?

findBy+fieldName e.g findByEmail to find an entity by its email.

  1. verbs in the method name: get, read, find, query,stream and count.
    • prefixes find also can be replaced with read get query stream
        private static final String QUERY_PATTERN = "find|read|get|query|stream";
      
    • findAllByXxx() are findByXxx()` identical.
    • The count verb, on the other hand, returns a count of matching objects, rather than the objects themselves.
  2. The subject of a repository method is optional.
    • readSpittersByFirstnameOrLastname() = readByFirstnameOrLastname()
    • readPuppiesByFirstnameOrLastname() = readThoseThingsWeWantByFirstnameOrLastname()
    • They’re all requal! Beccause the type of object being retrieved is determined by how you parameterize the JpaRepository interface, not the subject of the method name.
    • There is one exception to the subject being ignored. If the subject starts with the word Distinct, then the generated query will be written to ensure a distinct result set.
  3. The predicate specifies the properties that will constrain the result set.
    • Each condition must reference a property and may also specify a comparison operation.
    • If the comparison operator is left off, it’s implied to be an equals operation.
    • You may choose any other comparison operations,
    • When dealing with String properties, the condition may also include IgnoringCase or IgnoresCase.
    • you may also use AllIgnoringCase or AllIgnoresCase after all the conditions to ignore case for all conditions
    • conditional parts are separated by either And or Or
  4. Limiting Query Results
    • The results of query methods can be limited by using the first or top keywords
    • An optional numeric value can be appended to top or first to specify the maximum result size to be returned.
    • If the number is left out, a result size of 1 is assumed.
User findFirstByOrderByLastnameAsc();

 User findTopByOrderByAgeDesc();

 Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);

 Slice<User> findTop3ByLastname(String lastname, Pageable pageable);

 List<User> findFirst10ByLastname(String lastname, Sort sort);

 List<User> findTop10ByLastname(String lastname, Pageable pageable);

 

36. How are Spring Data repositories implemented by Spring at runtime?

For a Spring Data repository a JDK dynamic proxy is created which intercepts all calls to the repository.

The default behavior is to route calls to the default repository implementation, which in Spring Data JPA is the SimpleJpaRepository class.

37. What is @Query used for?

Spring @Query annotation is used for customizing methods of some instant repository.

@Query allows for specifying a query to be used with a Spring Data JPA repository method.

When the name of the named parameter is the same as the name of the argument in the method annotated with @Query, the @Param annoation is not needed.

But if the method argument has a different name, the @Param annotation is needed to tell Spring that the value of this argument is to be injected in the named parameter in the query.

Queries annotated to the query method take precedence over queries defined using @NamedQuery or named queries declared in orm.xml .

Annotation-based configuration has the advantage of not needing another cofiguration file to be edited, lowering maintenance effort.

@Query("select p from Person u where p.name like %?1%")
List<Person> findAllByName(String name);

@Query("select p from Person p where p.name= :n")
Person findOneByName(@Param("n") String name);

@Query("select p.name from Person p where p.id= :id")
String findNameById(Long id);

 




Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Leave a Reply

Your email address will not be published. Required fields are marked *