Any RuntimeException (unchecked exception) or Error will cause by default a rollback. Checked exceptions don’t cause a rollback
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.
Exception
RuntimeException
.2. Why does Spring prefer unchecked exceptions?
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
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
Spring data access exception family has three main branches:
org.springframework.dao.NonTransientDataAccessException
RecoverableDataAccessException
springframework.dao.TransientDataAccessException
.
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-based DataSources are the simples type. Spring has 3 types of them:
@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:
The Spring JdbcTemplate simplifies the use of JDBC by implementing common workflows for
Benefits are:
DataAccessException
Spring comes with three template classes to choose from:
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?
a 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:
Others:
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:
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?
9. How does the JdbcTemplate support generic queries? How does it return objects and lists/maps of objects?
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:
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:
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:
@transaction
TransactionTemplate
PlatformTransactionManager
Declarative transaction management is non-invasive.
@Configuration
PlatformTransactionManager
bean using @bean
@EnableTransactionManagement
@Configuration @EnableTransactionManagement public class TestDataConfig { @Bean public PlatformTransactionManager txManager(){ return new DataSourceTransactionManager(dataSource()); } }
@Transactional
@Service public class UserServiceImpl implements UserService { @Transactional(propagation = Propagation.REQUIRED, readOnly= true) @Override public User findById(Long id) { return userRepo.findById(id); } }
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:
TransactionTemplate
, which is recommended by Spring;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 interface, class, or method must have transactional semantics.
@Transactional
Settings
The transactionManager attribute value defines the transaction manager used to manage the transaction in the context of which the annotated method is executed
The readOnly attribute should be used for transactions that involve operations that do not modify the database (example: searching, counting records). Defalt FALSE.
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.
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.
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.
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.
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_REQUIRED
.ISOLATION_DEFAULT
.read/write
, which is read only = FALSE
.Annotation driven transaction settings:
mode
spring-aspects.jar
in the classpath as well as having load-time weaving (or compiletime weaving) enabled.proxyTargetClas
order
@Transactional
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:
In Spring we have the following isolation levels:
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:
@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:
Propagation.REQUIRED
: @Transactional(propagation = Propagation.REQUIRED)
UnexpectedRollbackException
.Propagation.REQUIRES_NEW
:
Propagation.NESTED
.
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 backPropagation.MANDATORY
.
Propagation.NEVER
.
Propagation.NOT_SUPPORTED
:
Propagation.SUPPORTS
.
@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.
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:
Method level:
Interface:
20. What does declarative transaction management mean?
For declarative transaction management:
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:
The @EnableTransactionManagement
annotation activates annotation‐based declarative transaction management.
Spring Container scans managed beans’ classes for the @Transactional
annotation.
When the annotation is found, it creates a proxy that wraps your actual bean instance.
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:
21. What is the default rollback policy? How can you override it?
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?
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).
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:
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
EntityManagers
are created by an EntityManagerFactory
obtained by calling the createEntityManagerFactory()
method of the PersistenceProvider.LocalEntityManagerFactoryBean
produces an application-managed EntityManagerFactory
.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
persistence.xml
.EntityManagerFactorys
are obtained through PersistenceProvider’s createContainerEntityManagerFactory()
method.LocalContainerEntityManagerFactoryBean
produces a container-managed EntityManagerFactory
.EntityManagerFactory
or EntityManager
instances within Java EE environments.
@PersistenceUnit
annotation expresses a dependency on an EntityManagerFactory
, and@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:
Benefits:
DataAccessException
hierarchy.Disadvantage:
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.
@PersistenceUnit
annotation expresses a dependency on an EntityManagerFactory
, and@PersistenceContext
expresses a dependency on a containermanaged EntityManager
instance.@PersistenceUnit
and @PersistenceContext
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
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 activePersistenceContextType.EXTENDED
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.
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.
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.
@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?
Declare dependencies: ORM dependency, db driver dependency, transaction manager dependency.
@Entity
classes
@Entity
marks classes as templates for domain objects, also called entities to database tables.@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.LocalEntityManagerFactoryBean
. It produces an application-managed EntityManagerFactory.EntityManagerFactory
using JNDI, use when app ran in Java EE serverLocalContainerEntityManagerFactoryBean
Define a DataSource
bean
Define a TransactionManager
bean
@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.,
DataSourceTransactionManager
: Suitable if you are only using JDBC
HibernateTransactionManager
JpaTransactionManager
:
JdoTransactionManage
JtaTransactionManager
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
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.
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.
Disable Spring Data Auto Configuration in SpringBoot:
It’s useful in testing.
Disable Using Annotation
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
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)
A 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
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.
prefixes find also can be replaced with read |
get | query | stream |
private static final String QUERY_PATTERN = "find|read|get|query|stream";
are
findByXxx()` identical.count
verb, on the other hand, returns a count of matching objects, rather than the objects themselves.readSpittersByFirstnameOrLastname()
= readByFirstnameOrLastname()
readPuppiesByFirstnameOrLastname()
= readThoseThingsWeWantByFirstnameOrLastname()
Distinct
, then the generated query will be written to ensure a distinct result set.predicate
specifies the properties that will constrain the result set.
String
properties, the condition may also include IgnoringCase
or IgnoresCase
.AllIgnoringCase
or AllIgnoresCase
after all the conditions to ignore case for all conditionsAnd
or Or
first
or top
keywordsUser 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);