spring & hibernate - koti karanki's trail · spring & hibernate 7 of 99 @cascade 71...
TRANSCRIPT
Spring & Hibernate 1 of 99
Spring & Hibernate
Interview preparation notes
Prepared By
Koti Karanki Email: [email protected]
Spring & Hibernate 2 of 99
Table of Content --------------------------------------------------
Spring 9
What is Spring 9
Open Sourced lightweight framework for building EE application 9
POJO Driven 9
Extension for building web applications 9
Benefits of Spring Framework 9
Light Weight 9
IOC 9
AOP 9
Container 9
MVC 9
Transaction Management 9
Security 9
Exception Handling 9
Application Context vs Bean Factory 9
Application Context Implementations 10
ClassPathXMLAC 10
FileSystemXMLAC 10
AnnotationConfigAC 10
WebAC 10
ApplicationContext Example 10
BeanFactory Example 11
Ways to register a Spring Bean 11
Injecting Java Collection 13
Spring MVC Plugging 13
Auto Wiring Types 14
No/Off 15
By Name 15
By Type 15
By Constructor 16
Auto Detect 16
Spring Singleton, Request, Session Beans and Thread Safety 16
Bean Lifecycle Management 17
Bean Container finds the Spring Bean Definition 18
Bean is created using Reflections 18
Its properties are resolved and set 18
Spring & Hibernate 3 of 99
setBeanName() of BeanNameAware is called 18
setBeanClassLoader() of BeanClassLoaderAware is called 18
setBeanFactory() of BeanFactoryAware is called 18
postProcessBeforeInitialization() of BeanPostProcessor is called 18
afterPropertiesSet() of InitializingBean is called 18
init-method is called 18
postProcessAfterInitialization() of BeanPostProcessor is called 18
destroy() of DisposableBean 18
destroy-method is called 18
Inner Bean 18
Spring Annotation 18
Definition 19
How to Enable annotations 19
Various Spring annotations 19
@Service 19
@Repository 19
@Component 19
@Transactional 19
@Scope 20
@Controller 21
@RestController 21
Controller vs RestController 21
@RequestMapping 21
@PathVariable 22
@RequestParam 22
@ModelAttribute 23
@SessionAttributes 24
Spring JDBC Template 26
Implementation classes 26
Example 26
Spring + Hibernate Integration 27
Ways to Integrate Spring & Database 29
Use JDBC Connection 29
Ways to Configure DataSource in Spring 29
Use DriverManagerDataSource (Plain, No pool) 29
Use Apache DBCP Common Pool 29
Use Apache C3P0 Common Pool 30
Use JNDI Data Source 30
Spring Transaction 30
Spring & Hibernate 4 of 99
Transaction Properties 30
Transaction Isolation issues 30
Transaction Isolation levels 31
J2EE Transaction model 31
Spring Transactional Management 32
Spring Transaction Managers (Implementations) 32
Spring Transaction Management approaches 34
IOC Injection types 37
Constructor based 37
Setter Based 37
Limit number of User Sessions 38
Inject property files in Spring 38
Product Prototype from Singleton 38
Lookup 38
Object Factory 38
Scoped Proxy 39
Cache 39
caching declaration 40
cache configuration 40
Declarative annotation-based caching 40
Custom Key Generation Declaration 41
Synchronized caching 41
Conditional caching 42
@CachePut annotation 42
@CacheEvict annotation 42
@Caching annotation 43
Enable caching annotations 43
JCache (JSR-107) annotations 44
36.6 Configuring the cache storage 44
36.6.1 JDK ConcurrentMap-based Cache 44
36.6.2 Ehcache-based Cache 44
36.6.3 Caffeine Cache 45
36.6.4 Guava Cache 45
Security 45
JAAS 45
Subject 46
Principal 46
Example for Tomcat 46
RestFul WS Security 49
Spring & Hibernate 5 of 99
Secure using web.xml 49
Secure using Security Context 49
Secure using Annotations 50
Spring Security 50
Configuration Class 50
Handler Class 51
Configuration XML 53
AOP 54
Key Components 54
Aspect 54
Join Point 54
Advice 55
Point Cut 55
Target Object 55
Interceptor 55
AOP Proxy 55
Weaving 55
Types of Advices 55
Before 55
After 55
After returning 55
After Throwing 56
Around 56
Example 56
Enable AspectJ 56
Aspect class to log 56
Best Practices 56
__________________________________________________________ 57
Hibernate 58
What is Hibernate!! 58
Benefits of Hibernate !! 58
What is JPA!! 58
Hibernate Architecture 58
Configuration Interface 59
Session Factory object 60
Session object 61
Transaction object 61
Query object 62
HQL Queries 62
Spring & Hibernate 6 of 99
HQL SELECT 62
HQL UPDATE 63
HQL DELETE 63
HQL INSERT 63
HQL AGGREGATION 63
HQL ORDER BY 64
HQL GROUP BY 64
HQL JOINS 64
SQL Queries 64
Scalar (Raw Data) values from Native Query 64
Entity Query 65
Criteria object 65
Example 65
SQL Restrictions 66
Order By 66
Projection 66
Example 67
Get() vs Load() 67
Load() 67
Get() 67
Save() vs SaveOrUpdate() 67
Save() vs Persist() 68
Named SQL Query 68
Named Query in XML Configuration 69
Named Query Annotation 69
Call Named/(Native Query) 70
Important Annotations 70
@Entity 70
@Table 70
@Entity vs @Table 70
@Access 71
@Id 71
@EmbeddedId 71
@Column 71
@GeneratedValue 71
@OneToOne 71
@OneToMany 71
@ManyToOne 71
@ManyToMany 71
Spring & Hibernate 7 of 99
@Cascade 71
@PrimayKeyJoinCoumn 72
Associations 72
1:M (One-To-Many) Association 72
M:1 (Many-to-One) Association 72
M:M (Many-to-Many) Association 73
Mapping Inheritance 74
Table per Hierarchy 74
Table per SubClass 74
Table for Concrete Class 75
openSession() vs getCurrentSession() 76
openSession() 76
getCurrentSession() 76
merge() vs update() 77
Cache 77
First Level Cache 77
Second Level Cache 78
Cache Providers 78
Cache Strategies 79
Cache Factory Configuration (EHCache) 80
Entity Configuration 80
EH Cache Configuration 80
Query Cache 82
Enable Query Cache Configuration 82
Lazy Loading 82
Fetching Strategies 83
FetchMode.SELECT 83
FetchMode.SELECT with BATCH SIZE 83
FetchMode.JOIN 83
FetchMode.SUBSELECT 84
Transaction Management 85
Transactions Management Types (Unmanaged vs Managed) 85
Managed Environment 85
Non-Managed Environment 86
Transaction Example 87
Optimistic Concurrency 88
Version check (either with int, long or TimeStamp) 88
Pessimistic Locking 88
Lock Mode 89
Spring & Hibernate 8 of 99
End of Session i.e. Session.close() 90
What is derived property!! 90
Sorted vs Ordered Collection 90
Collections Types in Hibernate 90
Hibernate Proxy 91
Hibernate Object equality 91
Session.lock() 91
Cascade 92
Example 92
Cascade Configuration 93
Cascade Types 93
Inverse 93
Example 1 - INVERSE in case of 1:M tables 94
Example 2 - INVERSE in case of M:N tables 95
Example 3 - INVERSE in case of M:N tables with Cascade combination 96
Ways to load object from Database!! 97
Design Patterns found Hibernate!! 97
Domain Model Pattern 97
Data Mapper Pattern 97
Proxy Pattern 97
Factory Pattern 98
Hibernate Best Practices 98
Spring & Hibernate 9 of 99
Spring & Hibernate --------------------------------------------------
Spring
1. What is Spring
● Open Sourced lightweight framework for building EE application
● POJO Driven
● Extension for building web applications
__________________________________________________________________________
2. Benefits of Spring Framework
● Light Weight
● IOC
● AOP
● Container
● MVC
● Transaction Management
● Security
● Exception Handling
__________________________________________________________________________
3. Application Context vs Bean Factory
Application Context Bean Factory
Pre installs beans (Aggressive Loading) Loads On Demand (Lazy Loading)
Loads resources, properties
Supports i18
Spring & Hibernate 10 of 99
Event publishing to Listeners
Annotations Support
Enterprise supports like Remoting, EJB connection
__________________________________________________________________________
4. Application Context Implementations
● ClassPathXMLAC
● FileSystemXMLAC
● AnnotationConfigAC
● WebAC
__________________________________________________________________________
5. ApplicationContext Example
ApplicationContext context = new FileSystemXmlApplicationContext
("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
__________________________________________________________________________
Spring & Hibernate 11 of 99
6. BeanFactory Example
● Using InputStream
InputStream is = new FileInputStream("beans.xml");
BeanFactory factory = new XmlBeanFactory(is);
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
● Using File System Resource
Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
● Using Class Path Resource
ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
__________________________________________________________________________
7. Ways to register a Spring Bean
● XML based Configuration
<!-- A bean definition with lazy init set on -->
<bean id = "helloBean" class = “org.karanki.spring.HelloBean"
lazy-init = "true/false">
init-method= “setUp”
destroy-method=”tearDown”
scope=”singleton|prototype|session|request|global”
<constructor-arg ref = "bar"/>
<constructor-arg ref = "baz"/>
<property name="workingDays" >
<ref bean="weekDays"/>
</property>
</bean>
<bean id = "bar" class = "x.y.Bar"/>
Spring & Hibernate 12 of 99
<bean id = "baz" class = "x.y.Baz"/>
<bean id="weekDays" class="org.karanki.spring.WeekDays">
<property name="weekDaysList">
<list>
<value>Monday</value>
<value>Tuesday</value>
</list>
</property>
</bean>
● Annotation based Configuration
<context:annotation-config/>
@Component
public class Message {
public String message() {
return “hello”;
}
}
@Component
public class Greet {
@Inject
Message message;
public String greet() {
return brean.message();
}
}
● Java based Configuration
<context:annotation-config/>
@Configuration
public class HelloWorldConfig {
Spring & Hibernate 13 of 99
@Bean
@Scope("prototype")
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
__________________________________________________________________________
8. Injecting Java Collection
● Set
● List
● Map
● Props __________________________________________________________________________
9. Spring MVC Plugging
● Dispatcher Servlet
Spring’s web MVC framework is, like many other web MVC frameworks, request-driven,
designed around a central Servlet that dispatches requests to controllers and offers other
functionality that facilitates the development of web applications. Spring’s DispatcherServlet
however, does more than just that. It is completely integrated with the Spring IoC container
and as such allows you to use every other feature that Spring has.
The request processing workflow of the Spring Web MVC DispatcherServlet is illustrated in
the following diagram. The pattern-savvy reader will recognize that the DispatcherServlet is
an expression of the "Front Controller" design pattern (this is a pattern that Spring Web MVC
shares with many other leading web frameworks).
Spring & Hibernate 14 of 99
<web-app> <servlet> <servlet-name>example</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>example</servlet-name> <url-pattern>/example/*</url-pattern> </servlet-mapping> </web-app>
__________________________________________________________________________
10. Auto Wiring Types
Spring & Hibernate 15 of 99
● No/Off
Default Behaviour - if nothing is mentioned , no autowiring is done
● By Name
<bean id = "greeting" class = “org.karanki.spring.Greeting"
autowire = "byName">
</bean>
<bean id = "message" class = "org.karanki.spring.Message"/>
public class Greeting {
private Message message;
}
● By Type
[Must have only one Type must exists within the application]
<bean id = "greeting" class = “org.karanki.spring.Greeting"
autowire = "byType">
</bean>
<bean id = "messageBean" class = "org.karanki.spring.Message"/>
public class Greeting {
private Message message;
}
Spring & Hibernate 16 of 99
● By Constructor
<bean id = "greeting" class = “org.karanki.spring.Greeting"
autowire = "constructor">
</bean>
<bean id = "message" class = "org.karanki.spring.Message"/>
public class Greeting {
private Message message;
public Greeting(Message message) {
This.message = message;
}
}
● Auto Detect
Spring first tries to wire using autowire by constructor, if it does not work, Spring tries to
autowire by byType.
● Limitation of Auto Wiring
○ Overriding: You can still specify dependencies using <constructor-arg> and
<property> settings which will always override autowiring.
○ Primitive data types: You cannot autowire simple properties such as primitives,
Strings, and Classes.
○ Confusing nature: Autowiring is less exact than explicit wiring, so if possible prefer
using explicit wiring.
__________________________________________________________________________
11. Spring Singleton, Request, Session Beans and Thread Safety
The Spring framework ecosystem comprising of so many useful frameworks has become
the backbone of many Java EE application. But at the core of all the spring products we still
have the Spring DI/IOC framework which has catapulted Spring to all new heights. As more
people are adopting Spring MVC or a JSF-Spring integration for their application, the Spring
beans are now more frequently used with request/session scope apart from their more
traditional counterparts of Singleton and Prototype scopes.
Spring & Hibernate 17 of 99
One of the initial curiosities of a developer just starting out with various Spring scopes is
that how do these scope behave in a web application and in situations which require
writing safe concurrency code. Well the answer to this no to over-think about these scope
as they behave exactly the way they have been named. Let’s take a example of JSF- Spring
integration wherein all the JSF beans are loaded by the Spring IOC container and Scope of
the beans are also defined using suppose Spring’s @Scope annotation.
The bean with @Scope(“request”) would be created for anywhere new incoming request
thus it’s thread safely is guaranteed since it’s created everytime a new request comes in.
Next is the @Scope(“session”) bean which would be same for every session of the user, in
case of user accessing the application through multiple tabs of the browser this bean scope
can surely give concurrency issues thus it’s important for the developer to make sure that
the state of the shared session data doesn’t become corrupt.
Now comes the @Scope(“singleton”) or the default scope of the Spring beans, how do
these singleton beans behave in a heavy load web application. Well first of all it’s
important to understand that “Singleton” means only one instance i.e. the application will
have only one instance of that bean. Now Spring framework doesn’t do anything under the
hood concerning the multithreaded behavior this Singleton bean i.e. it’s just a normal
Singleton bean and it’s up to the developer to handle the Concurrency issues pertaining to
this bean.
Now the question arises what kind of beans should be Singleton in a web application, well
the answer is pretty straightforward Any Bean without a STATE can be singleton . For
example beans that easily qualify to be singleton are DAO, Service , Controller these beans
don’t have their own states instead we leverage these beans in our application to perform
certain operations.. The DAO layer beans can be singleton as they don’t have their own
state but every thread accessing them using the DAO bean to perform certain thread
specific operation thus the DAO bean remains unaffected by it’s own concurrent access
because it doesn’t have it’s own state.
A really bad example of choosing a Singleton bean would be a bean that needs to maintain
it’s state in that case each thread would try to impose its own state on that bean thereby
corrupting the data. For Example if a Person bean with setters and getter for name and
age is made singleton. Now if multiple threads start accessing this bean they would keep
overriding the last set values of the Person’s instance thereby corrupting the state.
Conclusion – Remember the golden rule choose only those beans as singleton that don’t
have state.
__________________________________________________________________________
12. Bean Lifecycle Management
Spring & Hibernate 18 of 99
● Bean Container finds the Spring Bean Definition
● Bean is created using Reflections
● Its properties are resolved and set
● setBeanName() of BeanNameAware is called
● setBeanClassLoader() of BeanClassLoaderAware is called
● setBeanFactory() of BeanFactoryAware is called
● postProcessBeforeInitialization() of BeanPostProcessor is called
● afterPropertiesSet() of InitializingBean is called
● init-method is called
● postProcessAfterInitialization() of BeanPostProcessor is called
● destroy() of DisposableBean
● destroy-method is called
__________________________________________________________________________
13. Inner Bean
When a bean is only used as a property of another bean it can be declared as an inner
bean. Spring’s XML-based configuration metadata provides the use of <bean/> element
inside the <property/> or <constructor-arg/> elements of a bean definition, in order to
define the so-called inner bean. Inner beans are always anonymous and they are always
scoped as prototypes.
<bean id="CustomerBean" class="com.karanki.common.Customer">
<property name="person">
<bean class="com.karanki.common.Person">
<property name="name" value="Koti R. Karanki" />
<property name="age" value="43" />
</bean>
</property>
</bean>
__________________________________________________________________________
14. Spring Annotation
Spring & Hibernate 19 of 99
● Definition
An alternative to XML setups is provided by annotation-based configuration which relies on
the bytecode metadata for wiring up components instead of angle-bracket declarations.
Instead of using XML to describe a bean wiring, the developer moves the configuration into
the component class itself by using annotations on the relevant class, method, or field
declaration.
● How to Enable annotations
<context:annotation-config/>
● Various Spring annotations
● @Service
Annotate all your service classes with @Service. All your business logic should be in
Service classes.
● @Repository
Annotate all your DAO classes with @Repository. All your database access logic
should be in DAO classes.
● @Component
Annotate your other components (for example REST resource classes) with
@Component.
@Component is a generic stereotype for any Spring-managed component.
@Repository, @Service, and @Controller are specializations of @Component for
more specific use cases, for example, in the persistence, service, and presentation
layers, respectively.
● @Transactional
Configure your transactions with @Transactional spring annotation.
Spring & Hibernate 20 of 99
@Service
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyDAO companyDAO;
@Transactional
public Company findByName(String name) {
Company company = companyDAO.findByName(name);
return company;
}
...
}
The default @Transactional settings are as follows:
● Propagation setting is PROPAGATION_REQUIRED.
● Isolation level is ISOLATION_DEFAULT.
● Transaction is read/write.
● 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.
These default settings can be changed using various properties of the
@Transactional spring annotation.
● @Scope
As with Spring-managed components in general, the default and most common
scope for autodetected components is singleton. To change this default behavior,
use @Scope spring annotation.
@Component
@Scope("request")
public class ContactResource {
...
}
Similarly, you can annotate your component with @Scope("prototype") for beans
with prototype scopes.
Spring & Hibernate 21 of 99
● @Controller
Annotate your controller classes with @Controller.
@Controller
public class CompanyController {
...
}
● @RestController
A convenience annotation that is itself annotated with @Controller and
@ResponseBody.
● Controller vs RestController
@Controller is used to mark classes as Spring MVC Controller.
@RestController is a convenience annotation that does nothing more than adding
the @Controller and @ResponseBody annotations (see: Javadoc)
So the following two controller definitions should do the same
@Controller
@ResponseBody
public class MyController { }
@RestController
public class MyRestController { }
● @RequestMapping
You use the @RequestMapping spring annotation to map URLs onto an entire class
or a particular handler method. Typically the class-level annotation maps a specific
request path (or path pattern) onto a form controller, with additional method-level
annotations narrowing the primary mapping.
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
...
}
Spring & Hibernate 22 of 99
● @PathVariable
You can use the @PathVariable spring annotation on a method argument to bind it
to the value of a URI template variable. In our example below, a request path of
/company/techferry will bind companyName variable with 'techferry' value.
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
@RequestMapping("{companyName}")
public String getCompany(Map<String, Object> map,
@PathVariable String companyName) {
Company company = companyService.findByName(companyName);
map.put("company", company);
return "company";
}
...
}
● @RequestParam
You can bind request parameters to method variables using spring annotation
@RequestParam.
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
@RequestMapping("/companyList")
Spring & Hibernate 23 of 99
public String listCompanies(Map<String, Object> map,
@RequestParam int pageNum) {
map.put("pageNum", pageNum);
map.put("companyList", companyService.listCompanies(pageNum));
return "companyList";
}
...
}
Similarly, you can use spring annotation @RequestHeader to bind request headers.
● @ModelAttribute
An @ModelAttribute on a method argument indicates the argument should be
retrieved from the model. If not present in the model, the argument should be
instantiated first and then added to the model. Once present in the model, the
argument's fields should be populated from all request parameters that have
matching names. This is known as data binding in Spring MVC, a very useful
mechanism that saves you from having to parse each form field individually.
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
@RequestMapping("/add")
public String saveNewCompany(@ModelAttribute Company company) {
companyService.add(company);
return "redirect:" + company.getName();
}
...
}
Spring & Hibernate 24 of 99
● @SessionAttributes
@SessionAttributes spring annotation declares session attributes. This will typically
list the names of model attributes which should be transparently stored in the
session, serving as form-backing beans between subsequent requests.
@Controller
@RequestMapping("/company")
@SessionAttributes("company")
public class CompanyController {
@Autowired
private CompanyService companyService;
...
}
@SessionAttribute works as follows:
● @SessionAttribute is initialized when you put the corresponding attribute into
model (either explicitly or using @ModelAttribute-annotated method).
● @SessionAttribute is updated by the data from HTTP parameters when controller
method with the corresponding model attribute in its signature is invoked.
● @SessionAttributes are cleared when you call setComplete() on SessionStatus
object passed into controller method as an argument.
The following listing illustrate these concepts. It is also an example for pre-
populating Model objects.
@Controller
@RequestMapping("/owners/{ownerId}/pets/{petId}/edit")
@SessionAttributes("pet")
public class EditPetForm {
@ModelAttribute("types")
public Collection<PetType> populatePetTypes() {
return this.clinic.getPetTypes();
}
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pet") Pet pet,
Spring & Hibernate 25 of 99
BindingResult result, SessionStatus status) {
new PetValidator().validate(pet, result);
if (result.hasErrors()) {
return "petForm";
}
else {
this.clinic.storePet(pet);
status.setComplete();
return "redirect:owner.do?ownerId="
+ pet.getOwner().getId();
}
}
}
● @Required annotation This annotation simply indicates that the affected bean property must be populated at
configuration time, through an explicit property value in a bean definition or through
autowiring. The container throws BeanInitializationException if the affected bean property
has not been populated.
● @AutoWired annotation The @Autowired annotation provides more fine-grained control over where and how
autowiring should be accomplished. It can be used to autowire bean on the setter method
just like @Required annotation, on the constructor, on a property or pn methods with
arbitrary names and/or multiple arguments.
● @Qualified annotation When there are more than one beans of the same type and only one is needed to be
wired with a property, the @Qualifier annotation is used along with @Autowired
annotation to remove the confusion by specifying which exact bean will be wired.
● @Immutable An immutable entity may not be updated by the application. Updates to an immutable
entity will be ignored, but no exception is thrown. @Immutable must be used on root
entities only.
__________________________________________________________________________
Spring & Hibernate 26 of 99
15. Spring JDBC Template
Spring JdbcTemplate is a powerful mechanism to connect to the database and execute SQL
queries. It internally uses JDBC api, but eliminates a lot of problems of JDBC API.
It is the central class in the Spring JDBC support classes. It takes care of creation and
release of resources such as creating and closing of connection object etc. So it will not lead
to any problem if you forget to close the connection.
It handles the exception and provides the informative exception messages by the help of
exception classes defined in the org.springframework.dao package.
We can perform all the database operations by the help of JdbcTemplate class such as
insertion, updation, deletion and retrieval of the data from the database.
● Implementation classes ● JdbcTemplate
● NamedParameterJdbcTemplate
● SimpleJdbcTemplate
● SimpleJdbcInsert and SimpleJdbcCall
● Example
public class EmployeeDAO { @AutoWired JdbcTemplate jdbcTemplate; public int saveEmployee(Emp emp) { String qry = “insert into emp values(“ + emp.getID) + ”, “+ emp.getName() + “)”; Return jdbcTemplate.update(qry); } public Customer findByEmpId(int id{ String sql = "SELECT * FROM EMPWHERE EMP_ID = ?"; Emp emp= Emp().queryForObject( sql, new Object[] { id}, new EmpRowMapper()); return emp; } public List<Emp> findAll(){ String sql = "SELECT * FROM EMP";
Spring & Hibernate 27 of 99
List<Emp> emps = new ArrayList<Emp>(); List<Map> rows = getJdbcTemplate().queryForList(sql); for (Map row : rows) { Emp emp = new Emp(); emp.setId(rs.getInt("EMP_ID")); emp.setName(rs.getString("EMP_NAME")); emps.add(emp); } return emps; } public List<Emp> findAll(){ String sql = "SELECT * FROM EMP"; List<Emp> emps = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(Emp.class)); return emps; } } //EOF class EmployeeDAO public class EmpRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Emp emp = new Emp(); emp.setId(rs.getInt("EMP_ID")); emp.setName(rs.getString("EMP_NAME")); return emp; } }
Spring XML
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="ds"></property> </bean>
__________________________________________________________________________
16. Spring + Hibernate Integration
Spring & Hibernate 28 of 99
Spring XML
<!-- Data Source --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/TestDB" /> <property name="username" value="userName" /> <property name="password" value="password" /> </bean> <!--Hibernate Session Factory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="org.mano.app.model" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> </props> </property> <property name="annotatedClasses"> <list> <value>org.mano.app.model.Contact</value> <value>org.mano.app.model.Address</value> </list> </property> </bean> <!-- Transaction Management --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"> </bean>
DAO Implementation
public class EmpDAO { @AutoWired private SessionFactory sf; public void save(Emp emp) { Session session = sf.openSession();
Spring & Hibernate 29 of 99
Transaction tx = session.beginTransaction(); session.persist(emp); tx.commit(); session.close(); } public Collection<Employee> findAll() { return sf.getCurrentSession() .createQuery("from Employee e order by e.lastName, e.firstName") .list(); } } //EOF class EmpDAO
____________________________________________________________________________
17. Ways to Integrate Spring & Database
● Use JDBC Connection
● Configure Data Source
● Inject DataSource to DAO class
● Use DataSource.getConnection()
● Use Connection just like JDBC way from here
● Use Spring’s JDBC Template
__________________________________________________________________________
18. Ways to Configure DataSource in Spring
● Use DriverManagerDataSource (Plain, No pool)
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"><value>${jdbc.driverClassName}</value></property> <property name="url"><value>${jdbc.url}</value></property> <property name="username"><value>${jdbc.username}</value></property> <property name="password"><value>${jdbc.password}</value></property> </bean>
● Use Apache DBCP Common Pool
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/>
Spring & Hibernate 30 of 99
<property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <context:property-placeholder location="jdbc.properties"/>
● Use Apache C3P0 Common Pool
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <context:property-placeholder location="jdbc.properties"/>
● Use JNDI Data Source
● Configure Data Source in Application / Web Server (i.e. mysql-ds.xml)
● Register DS Bean in Spring configuration
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"><value>java:comp/env/jdbc/roseindiaDB_local</value></property> </bean>
__________________________________________________________________________
19. Spring Transaction
● Transaction Properties
● A (Atomic)
● C (Consistency)
● I (Isolation)
● D (Durable)
● Transaction Isolation issues
● Dirty reads
Spring & Hibernate 31 of 99
A transaction reads data that has been written by another transaction that has not
been committed yet.
● Non-Repeatable (fuzzy) reads
A transaction rereads data it has previously read and finds that another committed
transaction has modified or deleted the data.
● Phantom reads (or phantoms)
A transaction re-runs a query returning a set of rows that satisfies a search
condition and finds that another committed transaction has inserted additional
rows that satisfy the condition.
● Transaction Isolation levels
Isolation Level Dirty Read Non-Repeatable Read Phantom Read
READ UNCOMMITTED PERMITTED PERMITTED PERMITTED
READ COMMITTED --- PERMITTED PERMITTED
REPEATABLE READ --- --- PERMITTED
SERIALIZABLE --- ---
● J2EE Transaction model
Global Transaction
❏ Use to work with multiple transactional resources like RDBMS or Message Queue
(Pros)
❏ Managed by Application Server (WebSphere, Weblogic) using JTA (Cons)
❏ JNDI is required to use JTA
❏ Code can not be reused as JTA is available at server level(Cons)
❏ Example of Global Transaction : EJB CMT
Local Transaction
❏ Use to work with specific resource(transaction associated with JDBC)
❏ Can not work across multiple transaction resource opposite to Global transaction
(cons)
❏ Most of web application uses only single resources hence it is best option to use in
normal app.
Spring & Hibernate 32 of 99
● Spring Transactional Management
Comprehensive transaction support is among the most compelling reasons to use the
Spring Framework. The Spring Framework provides a consistent abstraction for
transaction management that delivers the following benefits:
● Consistent programming model across different transaction APIs such as Java
Transaction API (JTA), JDBC, Hibernate, Java Persistence API (JPA), and Java Data
Objects (JDO) - either for Local or Global Transactions
● Support for declarative transaction management.
● Simpler API for programmatic transaction management than complex transaction
APIs such as JTA.
● Excellent integration with Spring’s data access abstractions.
● Spring Transaction Managers (Implementations)
Instead of managing the transaction, Spring supports several transaction managers which
delegate the transaction management responsibilities to platform specific
implementations. Platform Transaction manager is the parent of all transaction manager
implementations.
● DataSourceTransactionManager (i.e. for JDBCTemplate)
org.springframework.transaction.PlatformTransactionManager Implementation for
a single JDBC javax.sql.DataSource. This class is capable of working in any
environment with any JDBC driver, as long as the setup uses a javax.sql.DataSource
as its Connection factory mechanism. Binds a JDBC Connection from the specified
DataSource to the current thread, potentially allowing for one thread-bound
Connection per DataSource.
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager"/>
● HibernateTransactionManager (For Hibernate Integration)
org.springframework.transaction.PlatformTransactionManager implementation
for a single Hibernate SessionFactory. Binds a Hibernate Session from the specified
factory to the thread, potentially allowing for one thread-bound Session per
factory. SessionFactory.getCurrentSession() is required for Hibernate access code
that needs to support this transaction handling mechanism, with the
SessionFactory being configured with SpringSessionContext.
Spring & Hibernate 33 of 99
Supports custom isolation levels, and timeouts that get applied as Hibernate
transaction timeouts.
<!-- Transaction Management --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"> </bean>
● JtaTransactionManager
org.springframework.transaction.PlatformTransactionManager implementation for
JTA, delegating to a backend JTA provider. This is typically used to delegate to a Java
EE server's transaction coordinator, but may also be configured with a local JTA
provider which is embedded within the application.
This transaction manager is appropriate for handling distributed transactions, i.e.
transactions that span multiple resources, and for controlling transactions on
application server resources (e.g. JDBC DataSources available in JNDI) in general.
For a single JDBC DataSource, DataSourceTransactionManager is perfectly sufficient,
and for accessing a single resource with Hibernate (including transactional cache),
HibernateTransactionManager is appropriate, for example.
For typical JTA transactions (REQUIRED, SUPPORTS, MANDATORY, NEVER), a plain
JtaTransactionManager definition is all you need, portable across all Java EE servers.
This corresponds to the functionality of the JTA UserTransaction, for which Java EE
specifies a standard JNDI name ("java:comp/UserTransaction"). There is no need to
configure a server-specific TransactionManager lookup for this kind of JTA usage.
Transaction suspension (REQUIRES_NEW, NOT_SUPPORTED) is just available with a
JTA TransactionManager being registered. Common TransactionManager locations
are autodetected by JtaTransactionManager, provided that the
"autodetectTransactionManager" flag is set to "true" (which it is by default).
When to use JTA:
★ Across Multiple Data Resources
★ Does not need to know about the DataSource, or any other specific
resources, because it uses the container’s global transaction management
infrastructure. Transaction Manager is expected configured in the
Application Server as a JNDI resource.
★
Spring & Hibernate 34 of 99
<bean id=”transactionManager” class=”org.springframework.transaction.jta.JtaTransactionManager> <property name=”transactonManagerName” ref= “java:/TransactionManager” /> </bean>
Do you need an application server for transaction management? The Spring Framework’s transaction management support changes traditional rules as to when an enterprise Java application requires an application server. In particular, you do not need an application server simply for declarative transactions through EJBs. In fact, even if your application server has powerful JTA capabilities, you may decide that the Spring Framework’s declarative transactions offer more power and a more productive programming model than EJB CMT. Typically you need an application server’s JTA capability only if your application needs to handle transactions across multiple resources, which is not a requirement for many applications. Many high-end applications use a single, highly scalable database (such as Oracle RAC) instead. Standalone transaction managers such as Atomikos Transactions and JOTM are other options. Of course, you may need other application server capabilities such as Java Message Service (JMS) and Java EE Connector Architecture (JCA). The Spring Framework gives you the choice of when to scale your application to a fully loaded application server. Gone are the days when the only alternative to using EJB CMT or JTA was to write code with local transactions such as those on JDBC connections, and face a hefty rework if you need that code to run within global, container-managed transactions. With the Spring Framework, only some of the bean definitions in your configuration file, rather than your code, need to change.
Spring Boot supports distributed JTA transactions across multiple XA resources using either an Atomikos or Bitronix embedded transaction manager. JTA transactions are also supported when deploying to a suitable Java EE Application Server.
● JpaTransactionManager
Extension of the org.springframework.transaction.PlatformTransactionManager
interface, indicating a native resource transaction manager, operating on a single
target resource. Such transaction managers differ from JTA transaction managers
in that they do not use XA transaction enlistment for an open number of resources
but rather focus on leveraging the native power and simplicity of a single target
resource.
● Spring Transaction Management approaches ○ Programmatic transaction management
Spring & Hibernate 35 of 99
This means that you have to manage the transaction with the help of programming.
That gives you extreme flexibility, but it is difficult to maintain.
○ Declarative transaction management
It is not sufficient to tell you simply to annotate your classes with the @Transactional
annotation, add @EnableTransactionManagement to your configuration, and then
expect you to understand how it all works. This section explains the inner workings of
the Spring Framework’s declarative transaction infrastructure in the event of
transaction-related issues.
The most important concepts to grasp with regard to the Spring Framework’s
declarative transaction support are that this support is enabled via AOP proxies, and
that the transactional advice is driven by metadata (currently XML- or annotation-
based). The combination of AOP with transactional metadata yields an AOP proxy that
uses a TransactionInterceptor in conjunction with an appropriate
PlatformTransactionManager implementation to drive transactions around method
invocations.
Conceptually, calling a method on a transactional proxy looks like this…
This means you separate transaction management from the business code. You only
use annotations or XML-based configuration to manage the transactions.
Spring & Hibernate 36 of 99
● Transactional Properties
○ Isolation
■ DEFAULT (uses underlying datasource isolation level)
■ READ_UNCOMMITTED
■ READ_COMMITTED
■ REPEATABLE_READS
■ SERIALIZABLE
○ Propagation
■ PROPAGATION_MANDATORY (supports current trans
■ NESTED
■ NEVER
■ NON-SUPPORTED
■ REQUIRED
■ REQUIRES_NEW
■ SUPPORTS
○ Timeout
This setting is used to define how long this transaction may run before timing
out (candidate for rolled back by the underlying transaction infrastructure).
○ Read-Only status
This setting is used to specify the a read-only transaction. As read only
transactions does not modify any data. Hence it is optimized in some case.
○ rollBackFor
Optional array of exception classes that must cause rollback.
○ noRollBackFor
Optional array of exception classes that must not cause rollback.
Declarative transaction management is preferable over programmatic transaction management though it is less flexible than programmatic transaction management, which allows you to control transactions through your code. But as a kind of crosscutting concern, declarative transaction management can be modularized with the AOP approach. Spring supports declarative transaction management through the Spring AOP framework.
○ Declarative transaction example
■ Using XML configuration
<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
Spring & Hibernate 37 of 99
<tx:advice id="txAdvice" transaction-manager="txManager"> <!-- the transactional semantics... --> <tx:attributes> <!-- all methods starting with 'get' are read-only --> <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException" no-rollback-for="InstrumentNotFoundException" /> <!-- other methods use the default transaction settings (see below) --> <tx:method name="*"/> </tx:attributes> </tx:advice>
■ Using Annotations
● Add @EnabledTransactionManagement to @Configuration class
(OR)
<tx:annotation-driven transaction-manager="txManager"/> to xml
● Add @Transactional to your class
@Transactional(readOnly = true) public class DefaultFooService implements FooService { public Foo getFoo(String fooName) { // do something } // these settings have precedence for this method @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void updateFoo(Foo foo) { // do something } }
__________________________________________________________________________
20. IOC Injection types
● Constructor based
● Setter Based
Spring & Hibernate 38 of 99
You can use both Constructor-based and Setter-based Dependency Injection. The best solution is using constructor arguments for mandatory dependencies and setters for optional dependencies.
__________________________________________________________________________
21. Limit number of User Sessions
<session-management invalid-session-url="/logout.html"> <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" /> </session-management>
__________________________________________________________________________
22. Inject property files in Spring
<bean id="propertyConfigurer" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> <property name="location" value="custom.properties" /> </bean>
__________________________________________________________________________
23. Product Prototype from Singleton
● Lookup
<bean id="prototype" class="ch.frankel.blog.Prototype" scope="prototype" /> <bean id="singleton" class="sample.MySingleton"> <lookup-method name="createPrototype" bean="prototype" /> </bean>
● Object Factory
@Component public class SingletonBean { @Autowired private ObjectFactory<PrototypeBean> prototypeFactory;
Spring & Hibernate 39 of 99
public void doSomething() { PrototypeBean prototypeBean = prototypeFactory.getObject(); prototypeBean.setX(1); prototypeBean.display(); } } @Component @Scope(value="prototype") public class PrototypeBean { // ... }
● Scoped Proxy
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"> <aop:scoped-proxy/> </bean> <bean id="userManager" class="com.foo.UserManager"> <property name="userPreferences" ref="userPreferences"/> </bean>
User Preference object is created for every session, since the scope is session. Object is created for
every request, if the scope is prototype.
__________________________________________________________________________
24. Cache
At its core, the abstraction applies caching to Java methods, reducing thus the number of
executions based on the information available in the cache. That is, each time a targeted method is
invoked, the abstraction will apply a caching behavior checking whether the method has been
already executed for the given arguments. If it has, then the cached result is returned without
having to execute the actual method; if it has not, then method is executed, the result cached and
returned to the user so that, the next time the method is invoked, the cached result is returned.
This way, expensive methods (whether CPU or IO bound) can be executed only once for a given set
of parameters and the result reused without having to actually execute the method again. The
caching logic is applied transparently without any interference to the invoker.
Spring & Hibernate 40 of 99
Obviously this approach works only for methods that are guaranteed to return the same output
(result) for a given input (or arguments) no matter how many times it is being executed.
If you have a multi-process environment (i.e. an application deployed on several nodes), you will
need to configure your cache provider accordingly. Depending on your use cases, a copy of the
same data on several nodes may be enough but if you change the data during the course of the
application, you may need to enable other propagation mechanisms.
Caching a particular item is a direct equivalent of the typical get-if-not-found-then- proceed-and-
put-eventually code blocks found with programmatic cache interaction: no locks are applied and
several threads may try to load the same item concurrently. The same applies to eviction: if several
threads are trying to update or evict data concurrently, you may use stale data. Certain cache
providers offer advanced features in that area, refer to the documentation of the cache provider
that you are using for more details.
To use the cache abstraction, the developer needs to take care of two aspects:
● caching declaration
- identify the methods that need to be cached and their policy
● cache configuration
- the backing cache where the data is stored and read from
● Declarative annotation-based caching
For caching declaration, the abstraction provides a set of Java annotations:
@Cacheable triggers cache population
@CacheEvict triggers cache eviction
@CachePut updates the cache without interfering with the method execution
@Caching regroups multiple cache operations to be applied on a method
@CacheConfig shares some common cache-related settings at class-level
Example
@Cacheable("books")
public Book findBook(ISBN isbn) {...}
Spring & Hibernate 41 of 99
● Custom Key Generation Declaration
Since caching is generic, it is quite likely the target methods have various signatures that
cannot be simply mapped on top of the cache structure. This tends to become obvious when
the target method has multiple arguments out of which only some are suitable for caching
(while the rest are used only by the method logic). For example:
@Cacheable("books")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
At first glance, while the two boolean arguments influence the way the book is found, they are
no use for the cache. Furthermore what if only one of the two is important while the other is
not?
For such cases, the @Cacheable annotation allows the user to specify how the key is
generated through its key attribute
@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
● Synchronized caching
In a multithreaded environment, certain operations might be concurrently invoked for the
same argument (typically on startup). By default, the cache abstraction does not lock anything
and the same value may be computed several times, defeating the purpose of caching.
For those particular cases, the sync attribute can be used to instruct the underlying cache
provider to lock the cache entry while the value is being computed. As a result, only one
thread will be busy computing the value while the others are blocked until the entry is
updated in the cache.
Spring & Hibernate 42 of 99
@Cacheable(cacheNames="foos", sync="true")
public Foo executeExpensiveOperation(String id) {...}
● Conditional caching
Sometimes, a method might not be suitable for caching all the time (for example, it might
depend on the given arguments). The cache annotations support such functionality through
the condition parameter which takes a SpEL expression that is evaluated to either true or
false. If true, the method is cached - if not, it behaves as if the method is not cached, that is
executed every time no matter what values are in the cache or what arguments are used. A
quick example - the following method will be cached only if the argument name has a length
shorter than 32:
@Cacheable(cacheNames="book", condition="#name.length() < 32")
public Book findBook(String name)
● @CachePut annotation
For cases where the cache needs to be updated without interfering with the method execution,
one can use the @CachePut annotation. That is, the method will always be executed and its result
placed into the cache (according to the @CachePut options). It supports the same options as
@Cacheable and should be used for cache population rather than method flow optimization:
@CachePut(cacheNames="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor)
● @CacheEvict annotation
The cache abstraction allows not just population of a cache store but also eviction. This process is
useful for removing stale or unused data from the cache. Opposed to @Cacheable, annotation
Spring & Hibernate 43 of 99
@CacheEvict demarcates methods that perform cache eviction, that is methods that act as triggers
for removing data from the cache. Just like its sibling, @CacheEvict requires specifying one (or
multiple) caches that are affected by the action, allows a custom cache and key resolution or a
condition to be specified but in addition, features an extra parameter allEntries which indicates
whether a cache-wide eviction needs to be performed rather then just an entry one (based on the
key):
@CacheEvict(cacheNames="books", allEntries=true)
public void loadBooks(InputStream batch)
● @Caching annotation
There are cases when multiple annotations of the same type, such as @CacheEvict or @CachePut
need to be specified, for example because the condition or the key expression is different between
different caches. @Caching allows multiple nested @Cacheable, @CachePut and @CacheEvict to
be used on the same method:
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)
● Enable caching annotations
It is important to note that even though declaring the cache annotations does not automatically
trigger their actions - like many things in Spring, the feature has to be declaratively enabled (which
means if you ever suspect caching is to blame, you can disable it by removing only one
configuration line rather than all the annotations in your code).
To enable caching annotations add the annotation @EnableCaching to one of your @Configuration
classes:
@Configuration
@EnableCaching
public class AppConfig {
}
Spring & Hibernate 44 of 99
● JCache (JSR-107) annotations
Since the Spring Framework 4.1, the caching abstraction fully supports the JCache standard
annotations: these are @CacheResult, @CachePut, @CacheRemove and @CacheRemoveAll as well
as the @CacheDefaults, @CacheKey and @CacheValue companions. These annotations can be
used right the way without migrating your cache store to JSR-107: the internal implementation
uses Spring’s caching abstraction and provides default CacheResolver and KeyGenerator
implementations that are compliant with the specification. In other words, if you are already using
Spring’s caching abstraction, you can switch to these standard annotations without changing your
cache storage (or configuration, for that matter).
● 36.6 Configuring the cache storage
○ 36.6.1 JDK ConcurrentMap-based Cache
<!-- simple cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
p:name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
p:name="books"/>
</set>
</property>
</bean>
● 36.6.2 Ehcache-based Cache
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-
ref="ehcache"/>
<!-- EhCache library setup -->
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-
location="ehcache.xml"/>
Spring & Hibernate 45 of 99
● 36.6.3 Caffeine Cache
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager">
<property name="caches">
<set>
<value>default</value>
<value>books</value>
</set>
</property>
</bean>
● 36.6.4 Guava Cache
<bean id="cacheManager" class="org.springframework.cache.guava.GuavaCacheManager">
<property name="caches">
<set>
<value>default</value>
<value>books</value>
</set>
</property>
</bean>
__________________________________________________________________________
25. Security
● JAAS
JAAS can simplify your Java security development by putting an abstraction layer between
your application and disparate underlying authentication and authorization mechanisms.
This independence from platforms and algorithms allows you to use different security
mechanisms without modifying your application-level code. As with most Java security
APIs, JAAS achieves this implementation-independence through an extensible framework
of pluggable service provider interfaces (SPIs): a set of abstract classes and interfaces to
which specific implementations are developed.
Spring & Hibernate 46 of 99
Using JAAS authentication from your application typically involves the following steps:
● Create a LoginContext
● Optionally pass a CallbackHandler to the LoginContext, for gathering or processing
authentication data
● Perform authentication by calling the LoginContext's login() method
● Perform privileged actions using the returned Subject (assuming login succeeds)
○ Subject
The Subject class represents an authenticated entity: an end-user or administrator, or
a Web service, device, or another process. The class contains three sets of security
information types:
Identities: In the form of one or more Principals
Public credentials: Such as name or public keys
Private credentials: Like passwords or private keys
○ Principal
Principals represent Subject identities. They implement the
java.security.Principal interface (which predates JAAS) and java.io.Serializable
○ Example for Tomcat
● Define Principal & Role
Spring & Hibernate 47 of 99
public class UserPrincipal implements Principal { public UserPrincipal(String name) { super(); this.name = name; } @Override public String getName() { return name; } } public class RolePrincipal implements Principal { public RolePrincipal (String name) { super(); this.name = name; } @Override public String getName() { return name; } }
● Define Login Module
public class UserPrincipal implements Principal { public UserPrincipal(String name) { super(); this.name = name; } @Override public String getName() { return name; } } public class RolePrincipal implements Principal { public RolePrincipal (String name) { super(); this.name = name; } @Override public String getName() {
Spring & Hibernate 48 of 99
return name; } }
● /META-INF/context.xml
<?xml version="1.0" encoding="UTF-8"?> <Context> <Realm className="org.apache.catalina.realm.JAASRealm" appName="BytesLoungeLogin" userClassNames="com.byteslounge.jaas.UserPrincipal" roleClassNames="com.byteslounge.jaas.RolePrincipal" /> </Context>
● jaas.config
JAVA_OPTS=$JAVA_OPTS "-
Djava.security.auth.login.config==$CATALINA_BASE/conf/jaas.config"
BytesLoungeLogin { com.byteslounge.jaas.BytesLoungeLoginModule required debug=true; };
● web.xml
<security-constraint> <web-resource-collection> <web-resource-name>Admin</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint> <security-role> <role-name>admin</role-name> </security-role>
Spring & Hibernate 49 of 99
<login-config> <auth-method>BASIC</auth-method> <realm-name>Admin</realm-name> </login-config>
● RestFul WS Security
○ Secure using web.xml
<web-app> <servlet> <servlet-name>RestServlet</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> </servlet> <servlet-mapping> <servlet-name>RestServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>Orders</web-resource-name> <url-pattern>/orders</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>default</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> </web-app>
○ Secure using Security Context
@Path("/stateless")
Spring & Hibernate 50 of 99
@Stateless(name = "JaxRSStatelessEJB") public class StlsEJBApp { ... @GET @Produces("text/plain;charset=UTF-8") @Path("/hello") public String sayHello(@Context SecurityContext sc) { if (sc.isUserInRole("admin")) return "Hello World!"; throw new SecurityException("User is unauthorized."); } }
○ Secure using Annotations
@Path("/helloworld") @RolesAllowed({"ADMIN", "ORG1"}) public class helloWorld { @GET @Path("sayHello") @Produces("text/plain") @RolesAllows("ADMIN") //Overrides the class level one public String sayHello() { return "Hello World!"; } }
● Spring Security
○ Configuration Class
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired CustomSuccessHandler customSuccessHandler; @Autowired public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");
Spring & Hibernate 51 of 99
auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN"); auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA"); //For DB based /* auth.jdbcAuthentication().dataSource(dataSource) .usersByUsernameQuery( "select username,password, enabled from users where username=?") .authoritiesByUsernameQuery( "select username, role from user_roles where username=?"); */ } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/home").access("hasRole('USER')") .antMatchers("/admin/**").access("hasRole('ADMIN')") .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") .and().formLogin().loginPage("/login").successHandler(customSuccessHandler) .usernameParameter("ssoId").passwordParameter("password") .and().csrf() .and().exceptionHandling().accessDeniedPage("/Access_Denied"); } }
○ Handler Class
@Component public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); @Override protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { String targetUrl = determineTargetUrl(authentication);
Spring & Hibernate 52 of 99
if (response.isCommitted()) { System.out.println("Can't redirect"); return; } redirectStrategy.sendRedirect(request, response, targetUrl); } /* * This method extracts the roles of currently logged-in user and returns * appropriate URL according to his/her role. */ protected String determineTargetUrl(Authentication authentication) { String url = ""; Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); List<String> roles = new ArrayList<String>(); for (GrantedAuthority a : authorities) { roles.add(a.getAuthority()); } if (isDba(roles)) { url = "/db"; } else if (isAdmin(roles)) { url = "/admin"; } else if (isUser(roles)) { url = "/home"; } else { url = "/accessDenied"; } return url; } private boolean isUser(List<String> roles) { if (roles.contains("ROLE_USER")) { return true; } return false; }
Spring & Hibernate 53 of 99
private boolean isAdmin(List<String> roles) { if (roles.contains("ROLE_ADMIN")) { return true; } return false; } private boolean isDba(List<String> roles) { if (roles.contains("ROLE_DBA")) { return true; } return false; } public void setRedirectStrategy(RedirectStrategy redirectStrategy) { this.redirectStrategy = redirectStrategy; } protected RedirectStrategy getRedirectStrategy() { return redirectStrategy; } }
○ Configuration XML
<beans:beans ...> <http auto-config="true" > <intercept-url pattern="/" access="hasRole('USER')" /> <intercept-url pattern="/home" access="hasRole('USER')" /> <intercept-url pattern="/admin**" access="hasRole('ADMIN')" /> <intercept-url pattern="/dba**" access="hasRole('ADMIN') and hasRole('DBA')" /> <form-login login-page="/login" username-parameter="ssoId" password-parameter="password" authentication-success-handler-ref="customSuccessHandler" authentication-failure-url="/Access_Denied" /> <csrf/> </http>
Spring & Hibernate 54 of 99
<authentication-manager > <authentication-provider> <user-service> <user name="bill" password="abc123" authorities="ROLE_USER" /> <user name="admin" password="root123" authorities="ROLE_ADMIN" /> <user name="dba" password="root123" authorities="ROLE_ADMIN,ROLE_DBA" /> </user-service> </authentication-provider> </authentication-manager> <beans:bean id="customSuccessHandler" class="com.websystique.springsecurity.configuration.CustomSuccessHandler" /> </beans:beans>
__________________________________________________________________________
26. AOP
One of the key components of Spring Framework is the Aspect oriented programming (AOP)
framework. Aspect-Oriented Programming entails breaking down program logic into distinct parts
called so-called concerns. The functions that span multiple points of an application are called cross-
cutting concerns and these cross-cutting concerns are conceptually separate from the application's
business logic. There are various common good examples of aspects like logging, auditing,
declarative transactions, security, caching, etc.
● Key Components
○ Aspect
This is a module which has a set of APIs providing cross-cutting requirements. For
example, a logging module would be called AOP aspect for logging. An application
can have any number of aspects depending on the requirement.
It is a class that contains advices, joinpoints etc.
○ Join Point
A join point is the specific point in the application such as method execution,
exception handling, changing object variable values etc. In Spring AOP a join points
is always the execution of a method.
Spring & Hibernate 55 of 99
○ Advice
This is the actual action to be taken either before or after the method execution.
This is an actual piece of code that is invoked during the program execution by
Spring AOP framework.
○ Point Cut
This is a set of one or more join points where an advice should be executed. You can
specify pointcuts using expressions or patterns as we will see in our AOP examples.
○ Target Object
It is the object i.e. being advised by one or more aspects. It is also known as proxied
object in spring because Spring AOP is implemented using runtime proxies.
○ Interceptor
It is an aspect that contains only one advice.
○ AOP Proxy
It is used to implement aspect contracts, created by AOP framework. It will be a JDK
dynamic proxy or CGLIB proxy in spring framework.
○ Weaving
It is the process of linking aspect with other application types or objects to create an
advised object. Weaving can be done at compile time, load time or runtime. Spring
AOP performs weaving at runtime.
● Types of Advices
○ Before
Run advice before the a method execution.
○ After
Run advice after the method execution, regardless of its outcome.
○ After returning
Run advice after the a method execution only if method completes successfully.
Spring & Hibernate 56 of 99
○ After Throwing
Run advice after the a method execution only if method exits by throwing an
exception.
○ Around
Run advice before and after the advised method is invoked.
● Example
●
○ Enable AspectJ
<aop:aspectj-autoproxy />
○ Aspect class to log
@Aspect public class LoggingAspect { @Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))") public void logBefore(JoinPoint joinPoint) { log.info("hijacked : " + joinPoint.getSignature().getName()); } }
__________________________________________________________________________
27. Best Practices
● Define singleton beans with names same as their class or interface names
● Place Spring bean configuration files under a folder instead of root folder
● Give common prefixes or suffixes to Spring bean configuration files
● Avoid using import elements within Spring XML configuration files as much as
possible
● Stay away from auto wiring in XML based bean configurations
● Always externalize bean property values with property placeholders
Spring & Hibernate 57 of 99
● Select default version-less XSD when importing namespace definitions
● Always place classpath prefix in resource paths
● Create a setter method even though you use field level auto wiring
● Create a separate service layer even though service methods barely delegate
their responsibilities to corresponding DAO methods
● Use stereotype annotations as much as possible when employing annotation
driven bean configuration
● Group handler methods according to related scenarios in different Controller
beans
● Place annotations over concrete classes and their methods instead of their
interfaces
● Prefer throwing runtime exceptions instead of checked exceptions from service
layer
● Manage transactions only in the service layer
● Mark transactions as readOnly=true when service methods only contain queries
● Be aware of false positives in transactional ORM integration tests
● Do not use DriverManagerDataSource
● Either use NamedParameterJdbcTemplate or JdbcTemplate for your JDBC
operations
● Use SessionFactory and EntityManager directly in your DAO beans
● Prefer to use apache Connection pooling bean
● Centric Business Handling Exceptions with error codes
● Prefer to use Spring Declarative Transaction Capability
● Transaction Attribute Settings
● Better to perform unit testing in the DAO layer
_______________________________________________________
___
Spring & Hibernate 58 of 99
Hibernate
28. What is Hibernate!!
Object-relational mapping or ORM is the programming technique to map application domain model
objects to the relational database tables. Hibernate is java based ORM tool that provides
framework for mapping application domain objects to the relational database tables and vice
versa.
Hibernate provides reference implementation of Java Persistence API, that makes it a great choice
as ORM tool with benefits of loose coupling.
● Benefits of Hibernate !!
● Eliminates all the boilerplate code, so we can focus on business logic.
● Support for XML as well as JPA annotations, that makes our code implementation
independent.
● Provides a powerful query language (HQL) that is similar to SQL.
● Open source project from Red Hat Community and used worldwide.
● Easy to integrate with other Java EE frameworks
● Lazy initialization using proxy objects
● Cache helps us in getting better performance.
● Native SQL queries, if needed
__________________________________________________________________________
29. What is JPA!!
The Java Persistence API (JPA) is a Java specification for accessing, persisting, and managing data
between Java objects / classes and a relational database. JPA was defined as part of the EJB 3.0
specification as a replacement for the EJB 2 CMP Entity Beans specification.
__________________________________________________________________________
30. Hibernate Architecture
The Hibernate architecture is layered to keep you isolated from having to know the underlying
APIs. Hibernate makes use of the database and configuration data to provide persistence services
(and persistent objects) to the application.
Spring & Hibernate 59 of 99
Hibernate uses various existing Java APIs, like JDBC, Java Transaction API(JTA), and Java Naming
and Directory Interface (JNDI). JDBC provides a rudimentary level of abstraction of functionality
common to relational databases, allowing almost any database with a JDBC driver to be supported
by Hibernate. JNDI and JTA allow Hibernate to be integrated with J2EE application servers.
__________________________________________________________________________
31. Configuration Interface
The Configuration object is the first Hibernate object you create in any Hibernate application and
usually created only once during application initialization. It represents a configuration or
properties file required by the Hibernate.
The Configuration object provides two keys components:
Database Connection
Spring & Hibernate 60 of 99
This is handled through one or more configuration files supported by Hibernate. These files are
hibernate.properties and hibernate.cfg.xml.
Class Mapping Setup
This component creates the connection between the Java classes and database tables.
Configuration config = new Configuration();
config.addResource(“myinstance/configuration.hbm.xml”);
config.setProperties( System.getProperties() );
SessionFactory sessions = config.buildSessionFactory();
__________________________________________________________________________
32. Session Factory object
Configuration object is used to create a SessionFactory object which in turn configures Hibernate
for the application using the supplied configuration file and allows for a Session object to be
instantiated.
The SessionFactory is a thread safe object and used by all the threads of an application.
The SessionFactory is heavyweight object so usually it is created during application start up and
kept for later use. You would need one SessionFactory object per database using a separate
configuration file. So if you are using multiple databases then you would have to create multiple
SessionFactory objects.
Session Factory objects are to be implemented using the singleton design pattern. Instances of SessionFactory are thread-safe and typically shared throughout an application. As these objects are heavy weight because they contains the connection information, hibernate configuration information and mapping files,location path. So creating number of instances will make our application heavyweight. But the session objects are not thread safe. So in short it is - SessionFactory objects are one per application and Session objects are one per client. Hence it would be one SessionFactory per DataSource. Your application may have more than one DataSource so you may have more than one SessionFactory in that instance. But you would not want to create a SessionFactory more than once in an application.
The internal state of a SessionFactory is immutable. Once it is created this internal state is set. This internal state includes all of the metadata about Object/Relational Mapping.
__________________________________________________________________________
Spring & Hibernate 61 of 99
33. Session object
A Session is used to get a physical connection with a database. The Session object is lightweight
and designed to be instantiated each time an interaction is needed with the database. Persistent
objects are saved and retrieved through a Session object.
The session objects should not be kept open for a long time because they are not usually thread
safe and they should be created and destroyed them as needed.
The lifecycle of a Session is bounded by the beginning and end of a logical transaction. (Long transactions might span several database transactions.) The main function of the Session is to offer create, read and delete operations for instances of mapped entity classes. Instances may exist in one of three states: transient: never persistent, not associated with any Session persistent: associated with a unique Session detached: previously persistent, not associated with any Session Transient instances may be made persistent by calling save(), persist() or saveOrUpdate(). Persistent instances may be made transient by calling delete(). Any instance returned by a get() or load() method is persistent. Detached instances may be made persistent by calling update(), saveOrUpdate(), lock() or replicate(). The state of a transient or detached instance may also be made persistent as a new persistent instance by calling merge(). save() and persist() result in an SQL INSERT, delete() in an SQL DELETE and update() or merge() in an SQL UPDATE. Changes to persistent instances are detected at flush time and also result in an SQL UPDATE. saveOrUpdate() and replicate() result in either an INSERT or an UPDATE. It is not intended that implementors be thread safe. Instead each thread/transaction should obtain its own instance from a SessionFactory. A Session instance is serializable if its persistent classes are serializable.
__________________________________________________________________________
34. Transaction object
A Transaction represents a unit of work with the database and most of the RDBMS supports
transaction functionality. Transactions in Hibernate are handled by an underlying transaction
manager and transaction (from JDBC or JTA).
Spring & Hibernate 62 of 99
This is an optional object and Hibernate applications may choose not to use this interface, instead
managing transactions in their own application code.
A typical transaction should use the following idiom: Session sess = factory.openSession(); Transaction tx; try { tx = sess.beginTransaction(); //do some work ... tx.commit(); } catch (Exception e) { if (tx!=null) tx.rollback(); throw e; } finally { sess.close(); }
__________________________________________________________________________
35. Query object
Query objects use SQL or Hibernate Query Language (HQL) string to retrieve data from the
database and create objects. A Query instance is used to bind query parameters, limit the number
of results returned by the query, and finally to execute the query.
__________________________________________________________________________
36. HQL Queries
Hibernate uses a powerful query language (HQL) that is similar in appearance to SQL. Compared
with SQL, however, HQL is fully object-oriented and understands notions like inheritance,
polymorphism and association.
● HQL SELECT
String hql = "FROM Employee";
Spring & Hibernate 63 of 99
Query query = session.createQuery(hql); List results = query.list(); [OR with FQ Class Name] String hql = "FROM com.hibernatebook.criteria.Employee"; Query query = session.createQuery(hql); List results = query.list();
● HQL UPDATE
Query query = session.createQuery("update Stock set stockName = :stockName" + " where stockCode = :stockCode"); query.setParameter("stockName", "DIALOG1"); query.setParameter("stockCode", "7277"); int result = query.executeUpdate();
● HQL DELETE
Query query = session.createQuery("delete Stock where stockCode = :stockCode"); query.setParameter("stockCode", "7277"); int result = query.executeUpdate();
● HQL INSERT
Query query = session.createQuery("insert into Stock(stock_code, stock_name)" + "select stock_code, stock_name from backup_stock"); int result = query.executeUpdate();
● HQL AGGREGATION
Query q=session.createQuery("select count(id) from Emp");
Spring & Hibernate 64 of 99
● HQL ORDER BY
String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC"; Query query = session.createQuery(hql); List results = query.list();
● HQL GROUP BY
String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E " + "GROUP BY E.firstName"; Query query = session.createQuery(hql); List results = query.list();
● HQL JOINS
from Cat as cat inner join cat.mate as mate left outer join cat.kittens as kitten
__________________________________________________________________________
37. SQL Queries
Hibernate provide option to execute native SQL queries through the use of SQLQuery object.
Hibernate SQL Query is very handy when we have to execute database vendor specific queries that
are not supported by Hibernate API. For example query hints or the CONNECT keyword in Oracle
Database.
For Hibernate Native SQL Query, we use Session.createSQLQuery(String query) to create the SQLQuery object and execute it
● Scalar (Raw Data) values from Native Query
SQLQuery query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee"); List<Object[]> rows = query.list(); for(Object[] row : rows){
Spring & Hibernate 65 of 99
Employee emp = new Employee(); emp.setId(Long.parseLong(row[0].toString())); emp.setName(row[1].toString()); emp.setSalary(Double.parseDouble(row[2].toString())); System.out.println(emp); }
● Entity Query
String sql = "SELECT * FROM EMPLOYEE"; SQLQuery query = session.createSQLQuery(sql); query.addEntity(Employee.class); List results = query.list();
________________________________________________________________
38. Criteria object
Criteria object are used to create and execute object oriented criteria queries to retrieve objects.
● Example
List cats = sess.createCriteria(Cat.class) .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) ) .add( Restrictions.disjunction() .add( Restrictions.isNull("age") ) .add( Restrictions.eq("age", new Integer(0) ) ) .add( Restrictions.eq("age", new Integer(1) ) ) .add( Restrictions.eq("age", new Integer(2) ) ) ) ) .list();
Spring & Hibernate 66 of 99
● SQL Restrictions
List cats = sess.createCriteria(Cat.class) .add( Restrictions.sqlRestriction("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) ) .list();
● Order By
List cats = sess.createCriteria(Cat.class) .add( Restrictions.like("name", "F%") .addOrder( Order.asc("name") ) .addOrder( Order.desc("age") ) .setMaxResults(50) .list(); List cats = sess.createCriteria(Cat.class) .add( Property.forName("name").like("F%") ) .addOrder( Property.forName("name").asc() ) .addOrder( Property.forName("age").desc() ) .setMaxResults(50) .list();
__________________________________________________________________________
39. Projection ● Projection is an interface in Hibernate, which is coming from
org.hibernate.criterion package.
● Projection can be applied on Criteria query.
● Projection is an Object Oriented representation of query result set projection in a
criteria query.
● To read partial entity, we need a Projection object for each property.
● If we want more than one property, then we need to add Projection objects to
ProjectionList and then we need to set ProjectionList object to Criteria.
Spring & Hibernate 67 of 99
● Example
Criteria criteria = session.createCriteria(Employee.class); Projection projection = Projections.property(“salary”); Projection projection2 = Projections.property(“departmentId”); Projection projection3 = Projections.property(“employeeName”); ProjectionList pList = Projections.projectionList(); pList.add(projection); pList.add(projection2); pList.add(projection3); criteria.setProjection(pList); List list = criteria.list();
__________________________________________________________________________
40. Get() vs Load()
● Load()
It will always return a “proxy” (Hibernate term) without hitting the database. In Hibernate,
proxy is an object with the given identifier value, its properties are not initialized yet, it just
look like a temporary fake object.
If no row found , it will throws an ObjectNotFoundException.
● Get()
It always hit the database and return the real object, an object that represent the database
row, not proxy. If no row found , it return null.
load() method will return a proxy (or the instance if already initialized), allowing lazy initialization and thus better performance
__________________________________________________________________________
41. Save() vs SaveOrUpdate()
Main difference between save and saveOrUpdate method is that save() generates a new identifier and INSERT record into database while saveOrUpdate can either INSERT or UPDATE based upon existence of record. Clearly saveOrUpdate is more flexible in terms of use but it involves an extra processing to find out whether record already exists in table or not. In summary save() method saves records into database by INSERT SQL query, Generates a new identifier and return the Serializable identifier back. On the other hand saveOrUpdate() method
Spring & Hibernate 68 of 99
either INSERT or UPDATE based upon existence of object in database. If persistence object already exists in database then UPDATE SQL will execute and if there is no corresponding object in database than INSERT will run.
__________________________________________________________________________
42. Save() vs Persist()
1. First difference between save and persist is there return type. Similar to save
method persist also INSERT records into database but return type of persist is void
while return type of save is Serializable object.
2. Another difference between persist and save is that both methods make a
transient instance persistent. However, persist() method doesn't guarantee that
the identifier value will be assigned to the persistent instance immediately, the
assignment might happen at flush time.
3. One more thing which differentiate persist and save method in Hibernate is that is
there behavior on outside of transaction boundaries. persist() method guarantees
that it will not execute an INSERT statement if it is called outside of transaction
boundaries. save() method does not guarantee the same, it returns an identifier,
and if an INSERT has to be executed to get the identifier (e.g. "identity" generator),
this INSERT happens immediately, no matter if you are inside or outside of a
transaction.
4. Fourth difference between save and persist method in Hibernate is related to
previous difference on save vs persist. Because of its above behavior of persist
method outside transaction boundary, it's useful in long-running conversations
with an extended Session context. On the other hand save method is not good in a
long-running conversation with an extended Session context.
__________________________________________________________________________
43. Named SQL Query
Hibernate provides Named Query that we can define at a central location and use them
anywhere in the code. We can create named queries for both HQL and Native SQL.
Spring & Hibernate 69 of 99
● Named Query in XML Configuration
<hibernate-mapping> <query name="findStockByStockCode"> <![CDATA[from Stock s where s.stockCode = :stockCode]]> </query> <sql-query name="SQL_GET_ALL_EMP_ADDRESS"> <![CDATA[select {e.*}, {a.*} from Employee e join Address a ON e.emp_id=a.emp_id]]> <return alias="e" class="com.journaldev.hibernate.model.Employee" /> <return-join alias="a" property="e.address"></return-join> </sql-query> </hibernate-mapping>
● Named Query Annotation
@Entity @Table(name = "ADDRESS") @NamedQueries({ @NamedQuery(name = "@HQL_GET_ALL_ADDRESS", query = "from Address") }) @NamedNativeQueries({ @NamedNativeQuery(name = "@SQL_GET_ALL_ADDRESS", query = "select emp_id, address_line1, city, zipcode from Address") }) public class Address { @Id @Column(name = "emp_id", unique = true, nullable = false) @GeneratedValue(generator = "gen") @GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") }) private long id; @Column(name = "address_line1") private String addressLine1; @OneToOne @PrimaryKeyJoinColumn private Employee employee; public long getId() { return id; }
Spring & Hibernate 70 of 99
public void setId(long id) { this.id = id; } public String getAddressLine1() { return addressLine1; } public void setAddressLine1(String addressLine1) { this.addressLine1 = addressLine1; } @Override public String toString() { return "AddressLine1= " + addressLine1 + ", City=" + city + ", Zipcode=" + zipcode; } }
● Call Named/(Native Query)
Query query = session.getNamedQuery("findStockByStockCode") .setString("stockCode", "7277"); Query query = session.getNamedQuery("findStockByStockCodeNativeSQL") .setString("stockCode", "7277");
__________________________________________________________________________
44. Important Annotations
● @Entity
● @Table
● @Entity vs @Table
@Entity(name="MyEntityName") @Table(name="MyEntityTableName")
Spring & Hibernate 71 of 99
class MyEntity {} then a table with name MyEntityTableName is created and the entity name is MyEntityName. Your JPQL query would be : select * from MyEntityName
● @Access
Used to define the access type, either field or property. Default value is field and if you want hibernate to use getter/setter methods then you need to set it to property.
● @Id
● @EmbeddedId
Used to define composite primary key in the entity bean.
● @Column
● @GeneratedValue
Used to define the strategy to be used for generation of primary key. Used in conjunction with javax.persistence.GenerationType enum
● @OneToOne
● @OneToMany
● @ManyToOne
● @ManyToMany
● @Cascade
Used to define the cascading between two entity beans, used with mappings. It works in
conjunction with org.hibernate.annotations.CascadeType
Spring & Hibernate 72 of 99
● @PrimayKeyJoinCoumn
Used to define the property for foreign key. Used with
org.hibernate.annotations.GenericGenerator and org.hibernate.annotations.Parameter
__________________________________________________________________________
45. Associations
Association mappings are one of the key features of JPA and Hibernate. They model the
relationship between two database tables as attributes in your domain model. That allows
you to easily navigate the associations in your domain model and JPQL or Criteria queries.
JPA and Hibernate support the same associations as you know from your relational
database model. You can use:
one-to-one associations,
many-to-one associations and
many-to-many associations.
You can map each of them as a uni- or bidirectional association. That means you can either
model them as an attribute on only one of the associated entities or on both. That has no
impact on your database mapping, but it defines in which direction you can use the
relationship in your domain model and JPQL or Criteria queries. I will explain that in more
details in the first example.
● 1:M (One-To-Many) Association
@Entity public class Order { @OneToMany @JoinColumn(name = “fk_order”) // fk_order column in the OrderItem table to join private List<OrderItem> items = new ArrayList<OrderItem>(); }
● M:1 (Many-to-One) Association
@Entity public class OrderItem { @ManyToOne //Many of current Object i.e. OrderItem to One Order @JoinColumn(name = “fk_order”) //Different DB column name i.e. fk_order
Spring & Hibernate 73 of 99
private Order order; }
● M:M (Many-to-Many) Association
@Entity @Table(name = "STUDENT") public class Student { @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "STUDENT_SUBJECT", joinColumns = { @JoinColumn(name = "STUDENT_ID") }, inverseJoinColumns = { @JoinColumn(name = "SUBJECT_ID") }) private List<Subject> subjects = new ArrayList<Subject>(); }
@Entity @Table(name = "SUBJECT") public class Subject { @ManyToMany(mappedBy="subjects") private List<Student> students = new ArrayList<Student>(); }
mappedBy attribute tells that this is the inverse side of relationship which is managed by “subjects” property of Student annotated with @JoinColumn.
The inverseJoinColumns attribute is responsible for the columns mapping of the inverse side. In the above example from the Student Entity : inverseJoinColumns = { @JoinColumn(name = "SUBJECT_ID") }) private List<Subject> subjects = new ArrayList<Subject>() That tells, SUBJECT_ID from STUDENT_SUBJECT is the relation as far as subjects mapping from the M:N table is concerned.
__________________________________________________________________________
Spring & Hibernate 74 of 99
46. Mapping Inheritance
Suppose we have an interface Payment with the implementers CreditCardPayment,
CashPayment, and ChequePayment.
● Table per Hierarchy
<class name="Payment" table="PAYMENT"> <id name="id" type="long" column="PAYMENT_ID"> <generator class="native"/> </id> <discriminator column="PAYMENT_TYPE" type="string"/> <property name="amount" column="AMOUNT"/> … <subclass name="CreditCardPayment" discriminator-value="CREDIT"> <property name="creditCardType" column="CCTYPE"/> ... </subclass> <subclass name="CashPayment" discriminator-value="CASH"> ... </subclass> <subclass name="ChequePayment" discriminator-value="CHEQUE"> ... </subclass> </class>
Exactly one table is required. There is a limitation of this mapping strategy: columns declared by
the subclasses, such as CCTYPE, cannot have NOT NULL constraints.
● Table per SubClass
<class name="Payment" table="PAYMENT"> <id name="id" type="long" column="PAYMENT_ID"> <generator class="native"/>
Spring & Hibernate 75 of 99
</id> <property name="amount" column="AMOUNT"/> ... <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"> <key column="PAYMENT_ID"/> <property name="creditCardType" column="CCTYPE"/> ... </joined-subclass> <joined-subclass name="CashPayment" table="CASH_PAYMENT"> <key column="PAYMENT_ID"/> ... </joined-subclass> <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT"> <key column="PAYMENT_ID"/> ... </joined-subclass> </class>
Four tables are required. The three subclass tables have primary key associations to the
superclass table so the relational model is actually a one-to-one association.
● Table for Concrete Class
<class name="Payment"> <id name="id" type="long" column="PAYMENT_ID"> <generator class="sequence"/> </id> <property name="amount" column="AMOUNT"/> ... <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"> <property name="creditCardType" column="CCTYPE"/> ... </union-subclass> <union-subclass name="CashPayment" table="CASH_PAYMENT"> ... </union-subclass> <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT"> ... </union-subclass> </class>
Spring & Hibernate 76 of 99
Three tables are involved for the subclasses. Each table defines columns for all properties of the
class, including inherited properties.
The limitation of this approach is that if a property is mapped on the superclass, the column name
must be the same on all subclass tables. The identity generator strategy is not allowed in union
subclass inheritance. The primary key seed has to be shared across all unioned subclasses of a
hierarchy.
If your superclass is abstract, map it with abstract="true". If it is not abstract, an additional table
(it defaults to PAYMENT in the example above), is needed to hold instances of the superclass.
__________________________________________________________________________
47. openSession() vs getCurrentSession()
● openSession()
When you call SessionFactory.openSession, it always create new Session object afresh and
give it to you. You need to explicitly flush and close these session objects. As session objects
are not thread safe, you need to create one session object per request in multithreaded
environment and one session per request in web applications too.
● getCurrentSession()
When you call SessionFactory. getCurrentSession, it will provide you session object which is
in hibernate context and managed by hibernate internally. It is bound to transaction scope.
When you call SessionFactory. getCurrentSession , it creates a new Session if not exists , else
use same session which is in current hibernate context. It automatically flush and close
session when transaction ends, so you do not need to do externally.
If you are using hibernate in single threaded environment , you can use getCurrentSession,
as it is faster in performance as compare to creating new session each time.
You need to add following property to hibernate.cfg.xml to use getCurrentSession method.
<session-factory>
Spring & Hibernate 77 of 99
<!-- Put other elements here -->
<property name="hibernate.current_session_context_class">
thread
</property>
</session-factory>
__________________________________________________________________________
48. merge() vs update()
You should use update() if you are sure that the Hibernate session does not contain an
already persistent instance with the same id and use merge() if you want to merge your
modifications at any time without considering the state of the session.
__________________________________________________________________________
49. Cache
● First Level Cache
Hibernate first level cache is associated with the Session object. Hibernate first level cache is
enabled by default and there is no way to disable it. However hibernate provides methods
through which we can delete selected objects from the cache or clear the cache completely.
Any object cached in a session will not be visible to other sessions and when the session is
closed, all the cached objects will also be lost.
● Hibernate First Level cache is enabled by default, there are no configurations needed for this.
● Hibernate first level cache is session specific, that’s why when we are getting the same data in same session there is no query fired whereas in other session query is fired to load the data.
● Hibernate first level cache can have old values, as you can see above that I have put my program to sleep for 10 seconds and in that time I updated the value (name from Pankaj to PankajK) in database but it didn’t get reflected in the same session. But in other session, we got the updated value.
● We can use session evict() method to remove a single object from the hibernate first level cache.
● We can use session clear() method to clear the cache i.e delete all the objects from the cache.
● We can use session contains() method to check if an object is present in the hibernate cache
Spring & Hibernate 78 of 99
or not, if the object is found in cache, it returns true or else it returns false. ● Since hibernate cache all the objects into session first level cache, while running bulk queries
or batch updates it’s necessary to clear the cache at certain intervals to avoid memory issues.
● Second Level Cache
A Hibernate Session is a transaction-level cache of persistent data. It is possible to
configure a cluster or JVM-level (SessionFactory-level) cache on a class-by-class and
collection-by-collection basis. You can even plug in a clustered cache. Be aware that caches
are not aware of changes made to the persistent store by another application. They can,
however, be configured to regularly expire cached data.
Hibernate Second Level cache is disabled by default but we can enable it through
configuration. Currently EHCache and Infinispan provides implementation for Hibernate
Second level cache and we can use them. We will look into this in the next tutorial for
hibernate caching.
● Cache Providers
Spring & Hibernate 79 of 99
● Cache Strategies
■ Read Only
This caching strategy should be used for persistent objects that will always read but
never updated. It’s good for reading and caching application configuration and
other static data that are never updated. This is the simplest strategy with best
performance because there is no overload to check if the object is updated in
database or not.
■ Read Write
It’s good for persistent objects that can be updated by the hibernate application.
However if the data is updated either through backend or other applications, then
there is no way hibernate will know about it and data might be stale. So while using
this strategy, make sure you are using Hibernate API for updating the data.
■ Non Restricted Read Write
If the application only occasionally needs to update data and strict transaction
isolation is not required, a nonstrict-read-write cache might be appropriate.
Spring & Hibernate 80 of 99
■ Transactional
The transactional cache strategy provides support for fully transactional cache
providers such as JBoss TreeCache. Such a cache can only be used in a JTA
environment and you must specify hibernate.transaction.manager_lookup_class.
● Cache Factory Configuration (EHCache)
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> <!-- enable second level cache and query cache --> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="net.sf.ehcache.configurationResourceName"> /myehcache.xml </property>
● Entity Configuration
@Entity @Cacheable @Cache(usage=CacheConurrencyStrategy.READ_ONLY | READ_WRITE | TRANSACTIONAL etc) public class User { ... }
● EH Cache Configuration
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <diskStore path="java.io.tmpdir/ehcache" /> <defaultCache maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120"
Spring & Hibernate 81 of 99
diskSpoolBufferSizeMB="30" maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" statistics="true"> <persistence strategy="localTempSwap" /> </defaultCache> <cache name="employee" maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="5" timeToLiveSeconds="10"> <persistence strategy="localTempSwap" /> </cache> <cache name="org.hibernate.cache.internal.StandardQueryCache" maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120"> <persistence strategy="localTempSwap" /> </cache> <cache name="org.hibernate.cache.spi.UpdateTimestampsCache" maxEntriesLocalHeap="5000" eternal="true"> <persistence strategy="localTempSwap" /> </cache> </ehcache>
Hibernate EHCache provides a lot of options, I won’t go into much detail but some of the
important configurations above are:
diskStore: EHCache stores data into memory but when it starts overflowing, it start writing
data into file system. We use this property to define the location where EHCache will write
the overflown data.
defaultCache: It’s a mandatory configuration, it is used when an Object need to be cached
and there are no caching regions defined for that.
cache name=”employee”: We use cache element to define the region and it’s
configurations. We can define multiple regions and their properties, while defining model
beans cache properties, we can also define region with caching strategies. The cache
properties are easy to understand and clear with the name.
Cache regions org.hibernate.cache.internal.StandardQueryCache and
org.hibernate.cache.spi.UpdateTimestampsCache are defined because EHCache was
giving warning to that.
Spring & Hibernate 82 of 99
● Query Cache
Hibernate can also cache resultset of a query. Hibernate Query Cache doesn’t cache the
state of the actual entities in the cache; it caches only identifier values and results of value
type. So it should always be used in conjunction with the second-level cache.
Query Cache is used to cache the results of a query. Read here on how to implement query
cache. When the query cache is turned on, the results of the query are stored against the
combination query and parameters. Every time the query is fired the cache manager
checks for the combination of parameters and query. If the results are found in the cache,
they are returned, otherwise a database transaction is initiated. As you can see, it is not a
good idea to cache a query if it has a number of parameters, because then a single
parameter can take a number of values. For each of these combinations the results are
stored in the memory. This can lead to extensive memory usage.
● Enable Query Cache Configuration
<property name="hibernate.cache.use_query_cache">true</property>
__________________________________________________________________________
50. Lazy Loading
Lazy setting decides whether to load child objects while loading the Parent Object. You need to
specify parent class.Lazy = true in hibernate mapping file. By default the lazy loading of the child
objects is true. This make sure that the child objects are not loaded unless they are explicitly
invoked in the application by calling getChild() method on parent. In this case hibernate issues a
fresh database call to load the child when getChild() is actually called on the Parent object. But in
some cases you do need to load the child objects when parent is loaded. Just make the lazy=false
and hibernate will load the child when parent is loaded from the database.
Examples: Address child of User class can be made lazy if it is not required frequently. But you may
need to load the Author object for Book parent whenever you deal with the book for online
bookshop.
Hibernate does not support lazy initialization for detached objects. Access to a lazy association
outside of the context of an open Hibernate session will result in an exception.
Spring & Hibernate 83 of 99
__________________________________________________________________________
51. Fetching Strategies
Assume One Customer having 50 Invoices, where Customer to Invoice Table is OneToMany.
● FetchMode.SELECT
@OneToMany(mappedBy = "customer") @Fetch(FetchMode.SELECT) private Set<Invoice> invoices;
The Hibernate FetchMode SELECT generates a query for each Invoice collection loaded. In total that gives 1 query to load the Customers and 50 additional queries to load the Invoice collections. This behavior is commonly named the N + 1 select problem. Executing 1 query will trigger N additional queries, where N is the amount of results returned from the first query.
● FetchMode.SELECT with BATCH SIZE
@OneToMany(mappedBy = "customer") @Fetch(FetchMode.SELECT) @BatchSize(size=25) private Set<Invoice> invoices;
In this example BatchSize reduces the total amount of queries to 3. One to load the Customers and two additional queries to load the Invoice collections for all customers. To put it simple: When an Invoice collection is loaded for a specific Customer, Hibernate will try to load the Invoice collection for up to 25 additional Customer entities which are currently in the session. The example has 50 Customers so loading the 50 collections of Invoices takes 2 queries.
● FetchMode.JOIN
@OneToMany(mappedBy = "customer") @Fetch(FetchMode.JOIN)
Spring & Hibernate 84 of 99
private Set<Invoice> invoices;
The amount of queries has been reduced to 1 by joining the Customers and Invoice collections. FetchMode JOIN always triggers an EAGER load so the Invoices are loaded when the Customers are loaded.
● FetchMode.SUBSELECT
@OneToMany(mappedBy = "customer") @Fetch(FetchMode.SUBSELECT) private Set<Invoice> invoices;
A SUBSELECT generates one query to load the Customers and one additional query to fetch all the Invoice collections. It is important to notice that all Invoices are loaded for which there is a corresponding Customer in the database. So even Invoice collections for who there are no matching Customers in the session will be retrieved.
Which Hibernate FetchMode should I use?
Which FetchMode to use depends heavily on the application, environment and typical
usage. The following guideline should be seen as a rough indication of where to start.
Try to play with the setting to see what works best in your application / environment:
FetchMode SELECT
Use this when you want a quick response time when working on a single entity. SELECT
creates small queries and only fetches the data which is absolutely needed. The use-
case in our example could be an application to which displays one Customer with its
Invoices.
BatchSize
BatchSize is useful when working with a fixed set of data. When you have a batch
processing 10 Customers at a time a BatchSize of 10 will drastically reduced the number
of queries needed.If the BatchSize is not set too high the query will most likely return a
manageable amount of data in a reasonable time.
Spring & Hibernate 85 of 99
FetchMode JOIN
As indicated you’ll have to worry about duplicated results. On the other hand JOIN
creates the least amount of queries. In a high latency environment a single JOIN could
be considerable faster than multiple SELECTS. Keep in mind that joining too much data
could put a strain on the database.
FetchMode SUBSELECT
If you’ve got an entity of which you know that there aren’t that many of them, and
almost all of them are in the session, then SUBSELECT should be a good choice. Just
keep in mind that all collections are fetched, even if the parent is not in the session. A
SUBSELECT when having a single Customer in session while there are 1000+ in the
database will be wasteful.
__________________________________________________________________________
52. Transaction Management
● Transactions Management Types (Unmanaged vs Managed)
Managed and Unmanaged are two different types of environments where Hibernate will fit
in the architecture comfortably. Both these environments have their own advantage and
disadvantages, it depends on the project business requirements and use case.
● Managed Environment
Managed Environment means that everything Hibernate needs will be handled by
the environment itself; transaction and connection pooling are two important things
Hibernate will require any compliant JEE server to provide.
Spring & Hibernate 86 of 99
Managed environments are also called container environment, they are widely
defined in a Java EE containers. Through using of managed environments, multiple
awareness are covered, even the transactions.
If we use hibernate within a container managed environment, then no need to
depend on Hibernate connection pool implementation, because the connection pool
for the server can be used.
Managed in application server using JTA
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
● Non-Managed Environment
Non-Managed Environment needs us to add some additional efforts by providing
Hibernate with all what it needs. Following this tutorial we will see with an example
to explain how to can configure Hibernate Framework in a Non-Managed
Environments, so no JEE container is required and even no need for Apache
Tomcat as well.
Spring & Hibernate 87 of 99
Non-managed environment requires us to handle our transactions manually, as we
would be seeing. Begin a transaction and commit of it is our responsibility.
Hibernate has integrated fluently with the C3P0 connection pool implementation.
Even hibernate provides us the ability to use another implementation, but still we
can rely on hibernate handling all of these excellently.
Non-Managed Transaction configuration
<bean id="transactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
● Transaction Example
Session session = null; Transaction tx = null; try{ session = HibernateUtil.getSessionFactory().openSession(); //OR // session = HibernateUtil.getSessionFactory().getCurrentSession(); tx = session.beginTransaction();
Spring & Hibernate 88 of 99
tx.setTimeout(5); //doSomething(session); tx.commit(); }catch(RuntimeException e){ try{ tx.rollback(); }catch(RuntimeException rbe){ log.error("Couldn’t roll back transaction", rbe); } throw e; }finally{ if(session!=null){ session.close(); } }
● Optimistic Concurrency
The only approach that is consistent with high concurrency and high scalability, is optimistic
concurrency control with versioning. Version checking uses version numbers, or timestamps,
to detect conflicting updates and to prevent lost updates.
● Version check (either with int, long or TimeStamp)
@Version
private int version;
● Pessimistic Locking
It is not intended that users spend much time worrying about locking strategies. It is usually
enough to specify an isolation level for the JDBC connections and then simply let the
database do all the work. However, advanced users may wish to obtain exclusive pessimistic
locks or re-obtain locks at the start of a new transaction.
Hibernate will always use the locking mechanism of the database; it never lock objects in
memory.
Spring & Hibernate 89 of 99
● Lock Mode
The LockMode class defines the different lock levels that can be acquired by
Hibernate. A lock is obtained by the following mechanisms:
● LockMode.WRITE
Is acquired automatically when Hibernate updates or inserts a row.
LockMode.UPGRADE can be acquired upon explicit user request using SELECT ...
FOR UPDATE on databases which support that syntax.
● LockMode.UPGRADE_NOWAIT
Can be acquired upon explicit user request using a SELECT ... FOR UPDATE NOWAIT
under Oracle.
● LockMode.READ
Is acquired automatically when Hibernate reads data under Repeatable
Read or Serializable isolation level. It can be re-acquired by explicit user
request.
● LockMode.NONE
Represents the absence of a lock. All objects switch to this lock mode at
the end of a Transaction. Objects associated with the session via a call to
update() or saveOrUpdate() also start out in this lock mode.
The "explicit user request" is expressed in one of the following ways:
● A call to Session.load(), specifying a LockMode.
● A call to Session.lock().
● A call to Query.setLockMode().
If Session.load() is called with UPGRADE or UPGRADE_NOWAIT, and the
requested object was not yet loaded by the session, the object is loaded
using SELECT ... FOR UPDATE. If load() is called for an object that is already
loaded with a less restrictive lock than the one requested, Hibernate calls
lock() for that object.
Session.lock() performs a version number check if the specified lock mode
is READ, UPGRADE or UPGRADE_NOWAIT. In the case of UPGRADE or
UPGRADE_NOWAIT, SELECT ... FOR UPDATE is used.
Spring & Hibernate 90 of 99
If the requested lock mode is not supported by the database, Hibernate
uses an appropriate alternate mode instead of throwing an exception. This
ensures that applications are portable.
● End of Session i.e. Session.close()
● flush the session
● commit the transaction
● close the session
● handle exceptions
__________________________________________________________________________
53. What is derived property!!
Derived properties are those properties which are not mapped to any columns of a database
table. Such properties are calculated at runtime by evaluation of any expressions.
__________________________________________________________________________
54. Sorted vs Ordered Collection
__________________________________________________________________________
55. Collections Types in Hibernate
● Bag (UnOrdered/UnIndexed List)
Spring & Hibernate 91 of 99
● List
● Set
● Array
● Map
__________________________________________________________________________
56. Hibernate Proxy
Mapping of classes can be made into a proxy instead of a table. A proxy is returned
when actually a load is called on a session. The proxy contains actual method to load
the data. The proxy is created by default by Hibernate, for mapping a class to a file.
The code to invoke Jdbc is contained in this class.
● The proxy attribute enables lazy initialization of persistent instances of the
class.
● Hibernate will initially return CGLIB proxies which implement the named
interface.
● The actual persistent object will be loaded when a method of the proxy is
invoked.
__________________________________________________________________________
57. Hibernate Object equality
● ===
● equals()
● obj1.getId().equals(obj2.getId())
__________________________________________________________________________
58. Session.lock()
session.lock() method of session class is used to re attach an object which has been detached
earlier. This method of reattaching doesn’t check for any data synchronization in database
while reattaching the object and hence may lead to lack of synchronization in data.
__________________________________________________________________________
Spring & Hibernate 92 of 99
59. Cascade
Cascade is a convenient feature to save the lines of code needed to manage the state of
the other side manually (i.e associations).
● Example
For example, assume Department to Employee entity having One to Many relationship as
below
@Entity
public class Department {
@OneToMany
private Set<Employee> employees;
}
@Entity
public class Employee {
@ManyToOne
private Department department;
}
//code to insert
Employee emp = new Employee();
Department dept = new Department();
emp.setDepartment(dept);
dept.getEmployees().add(emp);
emp.save();
dept.save();
In the above code, employee & department both have to be explicitly saved. With Cascade
PERSIST, employee is automatically saved, when department is saved in cascaded manner.
Spring & Hibernate 93 of 99
● Cascade Configuration
@Cascade(CascadeType.PERSIST)
private List<Object> obj;
//OR
@OneToMany(cascade = CascadeType.PERSIST)
private List<Object> obj;.
● Cascade Types
CascadeType.PERSIST : means that save() or persist() operations cascade to related
entities.
CascadeType.MERGE : means that related entities are merged when the owning entity is
merged.
CascadeType.REFRESH : does the same thing for the refresh() operation.
CascadeType.REMOVE : removes all related entities association with this setting when the
owning entity is deleted.
CascadeType.DETACH : detaches all related entities if a “manual detach” occurs.
CascadeType.ALL : is shorthand for all of the above cascade operations
__________________________________________________________________________
60. Inverse
Always put inverse=”true” in your collection variable ?
There are many Hibernate articles try to explain the “inverse” with many Hibernate “official”
jargon, which is very hard to understand (at least to me). In few articles, they even suggested
that just forget about what is “inverse”, and always put inverse=”true” in the collection
variable.
Spring & Hibernate 94 of 99
This statement is always true – “put inverse=true in collection variable”, but do not blindfold
on it, try to understand the reason behind is essential to optimal your Hibernate
performance.
● Example 1 - INVERSE in case of 1:M tables
Spring & Hibernate 96 of 99
● Example 3 - INVERSE in case of M:N tables with Cascade combination
In case of many-to-many relation through intermediary table; "Cascade" says
whether a record will be created/updated in the child table. Whereas "Inverse" says
whether a record will be created/updated in the intermediary table
e.g. Assume below scenario 1 student can have multiple phones. So Student class has
property for Set of phones. Also 1 Phone can be owned by multiple students. So Phone
class has property for Set of Students. This mapping is mentioned in stud_phone table.
So there are three tables viz. Student, Phone and stud_phone (intermediary) table.
Mapping might look like:
<class name=”com.domain.Student” table=””>
<set name="phoneset" table="stud_phone" cascade="save-update"
inverse="true">
<key column="mapping_stud_id">< /key>
<many-to-many class="com.domain.Phone" column="mapping_phon_id"/>
</set>
</class>
A new student object is created and 2 new phone objects are added to its set when
session.save(student_obj) is called. Depending upon "cascade" and "inverse" settings
different queries will be fired.
Below are different combinations of cascade and inverse and their impact.
1) CASCADE IS NONE and INVERSE is false
Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)
2) CASCADE is NONE and INVERSE is true
Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
3) CASCADE is save-update and INVERSE is false
Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)
Hibernate: insert into stud_phone (mapping_stud_id, mapping_phon_id) values (?, ?)
4) CASCADE is save-update and INVERSE true
Spring & Hibernate 97 of 99
Hibernate: insert into STUDENT (Name, stud_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
Hibernate: insert into phone (phone_num, phone_id) values (?, ?)
As it can be seen, only when CASCADE was save-update the records were created in PHONE
table also. Otherwise not.
When INVERSE was false ( i.e. Student was the owner of relationship ) the intermediary
table STUD_PHONE was updated. When inverse is true, Phone is owner of relationship, so
even though a new student was created, the intermediary table was not updated.
So in case of relation of two entities, "cascade" affects other entity table and "inverse"
effects intermediary table. So their effect is independent.
__________________________________________________________________________
61. Ways to load object from Database!!
● Using HQL
● Using Identified (i.e. Session.get())
● Using Criteria API
● Using Standard/Native SQL
__________________________________________________________________________
62. Design Patterns found Hibernate!!
● Domain Model Pattern
An object model of the domain that incorporates both behavior and data.
● Data Mapper Pattern
A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between
a persistent data store (often a relational database) and an in-memory data
representation (the domain layer). The goal of the pattern is to keep the in-memory
representation and the persistent data store independent of each other and the data
mapper itself. The layer is composed of one or more mappers (or Data Access Objects),
performing the data transfer.
● Proxy Pattern
Lazy loading-Proxy Design pattern is one of the Structural design pattern
Spring & Hibernate 98 of 99
● Factory Pattern
SessionFactory - Factory Pattern is one of the Creational Design pattern
__________________________________________________________________________
63. Hibernate Best Practices
● Always check the primary key field access, if it’s generated at the database layer then
you should not have a setter for this.
● By default hibernate set the field values directly, without using setters. So if you want
hibernate to use setters, then make sure proper access is defined as
@Access(value=AccessType.PROPERTY).
● If access type is property, make sure annotations are used with getter methods and
not setter methods. Avoid mixing of using annotations on both field and getter
methods.
● Use native sql query only when it can’t be done using HQL, such as using database
specific feature.
● If you have to sort the collection, use ordered list rather than sorting it using
Collection API.
● Use named queries wisely, keep it at a single place for easy debugging. Use them for
commonly used queries only. For entity specific query, you can keep them in the
entity bean itself.
● For web applications, always try to use JNDI DataSource rather than configuring to
create connection in hibernate.
● Avoid Many-to-Many relationships, it can be easily implemented using bidirectional
One-to-Many and Many-to-One relationships.
● For collections, try to use Lists, maps and sets. Avoid array because you don’t get
benefit of lazy loading.
● Do not treat exceptions as recoverable, rollback the Transaction and close the
Session. If you do not do this, Hibernate cannot guarantee that in-memory state
accurately represents the persistent state.
● Prefer DAO pattern for exposing the different methods that can be used with entity
bean
● Prefer lazy fetching for associations
● You must have a default no-argument constructor for your persistent classes and
there should be getXXX() (i.e accessor/getter) and setXXX( i.e. mutator/setter)
methods for all your persistable instance variables.
● You should implement the equals() and hashCode() methods based on your business
key and it is important not to use the id field in your equals() and hashCode()
Spring & Hibernate 99 of 99
definition if the id field is a surrogate key (i.e. Hibernate managed identifier). This is
because the Hibernate only generates and sets the field when saving the object.
● It is recommended to implement the Serializable interface. This is potentially useful if
you want to migrate around a multi-processor cluster.
● The persistent class should not be final because if it is final then lazy loading cannot
be used by creating proxy objects.
● Use XDoclet tags for generating your *.hbm.xml files or Annotations (JDK 1.5
onwards), which are less verbose than *.hbm.xml files.
__________________________________________________________________________