Click here to download eclipse supported ZIP file
Hibernate update should be used where we know that we are only updating the entity information. This operation adds the entity object to persistent context and further changes are tracked and saved when transaction is committed. Let’s check this behavior with a simple program.
Modifying persistent objects
Transactional persistent instances (i.e. objects loaded, saved, created or
queried by the Session
) can be manipulated by the application,
and any changes to persistent state will be persisted when the Session
is flushed. This is discussed later in this chapter. There is no need
to call a particular method (like update()
, which has a different
purpose) to make your modifications persistent. The most straightforward way to update
the state of an object is to load()
it
and then manipulate it directly while the Session
is open:
EmployeeBean eb = (EmployeeBean) sess.load( EmployeeBean.class, new Long(69) );
eb.setName("PK");
sess.flush(); // changes to eb are automatically detected and persisted
Sometimes this programming model is inefficient, as it requires in the same session both an SQL
SELECT
to load an object and an SQL UPDATE
to persist its updated state. Hibernate offers an
alternate approach by using detached instances.
Important
Hibernate does not offer its own API for direct execution of
UPDATE
or DELETE
statements. Hibernate is a
state management service, you do not have to think in
statements to use it. JDBC is a perfect API for executing
SQL statements, you can get a JDBC Connection
at any time
by calling session.connection()
. Furthermore, the notion
of mass operations conflicts with object/relational mapping for online
transaction processing-oriented applications. Future versions of Hibernate
can, however, provide special mass operation functions.
Modifying detached objects
Many applications need to retrieve an object in one transaction, send it to the
UI layer for manipulation, then save the changes in a new transaction.
Applications that use this kind of approach in a high-concurrency environment
usually use versioned data to ensure isolation for the "long" unit of work.
Hibernate supports this model by providing for reattachment of detached instances
using the Session.update()
or Session.merge()
methods:
// in the first session
EmployeeBean eb = (EmployeeBean) firstSession.load(EmployeeBean.class, ebId);
EmployeeBean eb2 = new EmployeeBean();
firstSession.save(eb);
// in a higher layer of the application
eb2.setFirstName("CV");
// later, in a new session
secondSession.update(eb); // update eb
secondSession.update(eb2); // update eb2
If the EmployeeBean
with identifier Id
had already
been loaded by secondSession
when the application tried to
reattach it, an exception would have been thrown.
Use update()
if you are certain that the session does
not contain an already persistent instance with the same identifier. Use
merge()
if you want to merge your modifications at any time
without consideration of the state of the session. In other words, update()
is usually the first method you would call in a fresh session, ensuring that
the reattachment of your detached instances is the first operation that is executed.
The application should individually update()
detached instances
that are reachable from the given detached instance only if it wants
their state to be updated. This can be automated using transitive
persistence.
Here is the example code to test update functionality :
This is hibernate.cfg.xml file for connecting the postgreSQL database.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- <session-factory> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
hibernate word is optional <property name="connection.url">jdbc:oracle:thin:@localhost:1521:ORCL</property>
<property name="hibernate.connection.username">kcv</property> <property name="hibernate.connection.password">kcv</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="show_sql">true</property> <mapping resource="Employee.hbm.xml"/>
</session-factory> -->
<session-factory>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hbm2ddl.auto">create</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/hibernate</property>
<property name="connection.username">postgres</property>
<property name="connection.password">password</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
<mapping resource="EmployeeBean.hbm.xml" />
</session-factory>
</hibernate-configuration>
|
This is EmployeeBean.hbm.xml mapping file for map the Entity(POJO) class to columns.
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.cv.hibernate.model.EmployeeBean" table="EMPLOYEE_UPDATE"> <id name="id" column="EID" type="java.lang.Long"> </id> <property name="firstName" type="java.lang.String"> <column name="FIRSTNAME" length="29" not-null="true" /> </property> <property name="lastName" type="java.lang.String"> <column name="LASTNAME" length="29" not-null="true" /> </property> <property name="email" type="java.lang.String"> <column name="EMAIL" length="39" not-null="true" /> </property> </class> </hibernate-mapping>
|
This is EmployeeBean.java Entity(POJO) class having the fields needs to be configured in mapping file.
package com.cv.hibernate.model;
/**
* @author Chandra Vardhan
*/
public class EmployeeBean {
private long id;
private String firstName;
private String lastName;
private String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
} |
This is Update.java main class having the application business logic.
package com.cv.hibernate;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import com.cv.hibernate.model.EmployeeBean;
import com.cv.hibernate.util.HibernateUtil;
/**
* @author Chandra Vardhan
*/
public class Update {
private final static Logger logger = Logger.getLogger(Update.class);
public static void main(String[] args) throws Exception {
Session session = HibernateUtil.getSession();
EmployeeBean eb = new EmployeeBean();
eb.setId(101);
eb.setFirstName("nara");
eb.setLastName("kodam");
eb.setEmail("meetkodam@gmail.com");
session.beginTransaction();
session.update(eb);
logger.info(eb.getId() + " " + eb.getFirstName() + " " + eb.getLastName() + " " + eb.getEmail());
session.getTransaction().commit();
HibernateUtil.closeSession();
}
} |
This is HibernateUtil.java utility class for getting the database connection.
package com.cv.hibernate.util;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import com.cv.hibernate.model.EmployeeBean;
/**
* @author Chandra Vardhan
*/
/**
* Configures and provides access to Hibernate sessions, tied to the current
* thread of execution. Follows the Thread Local Session pattern, see
* {@link http://hibernate.org/42.html }.
*/
public class HibernateUtil {
private final static Logger logger = Logger.getLogger(HibernateUtil.class);
/**
* Location of hibernate.cfg.xml file. Location should be on the classpath
* as Hibernate uses #resourceAsStream style lookup for its configuration
* file. The default classpath location of the hibernate config file is in
* the default package. Use #setConfigFile() to update the location of the
* configuration file for the current session.
*/
private static String CONFIG_FILE_LOCATION = "hibernate.cfg.xml";
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new Configuration();
private static SessionFactory sessionFactory;
static {
try {
configuration = configuration.configure(CONFIG_FILE_LOCATION);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
logger.info("%%%% Connection successful %%%%");
} catch (Exception e) {
logger.error("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateUtil() {
}
/**
* Returns the ThreadLocal Session instance. Lazy initialize the
* <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}
/**
* Rebuild hibernate session factory
*
*/
public static void rebuildSessionFactory() {
try {
configuration = configuration.configure(CONFIG_FILE_LOCATION);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
logger.info("%%%% Connection successful %%%%");
} catch (Exception e) {
logger.error("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
System.exit(0);
}
}
/**
* return session factory
*
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* return hibernate configuration
*
*/
public static Configuration getConfiguration() {
return configuration;
}
public static void saveOrUpdate() {
Session session = getSession();
EmployeeBean eb = new EmployeeBean();
eb.setId(new Long(101));
eb.setFirstName("chandra");
eb.setLastName("vardhan");
eb.setEmail("meetkodam@gmail.com");
session.beginTransaction();
session.saveOrUpdate(eb);
logger.info("Saved successful...");
session.getTransaction().commit();
session.close();
}
} |
This is log4j.properties file having the entries for logging the information into the console/file.
#By default enabling Console appender
# Root logger option
log4j.rootLogger=INFO, stdout
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-5p [%c]:%L -->> %m%n
# Redirect log messages to a log file
#log4j.appender.file=org.apache.log4j.RollingFileAppender
#log4j.appender.file.File=C:\\servlet-application.log
#log4j.appender.file.MaxFileSize=5MB
#log4j.appender.file.MaxBackupIndex=10
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
|
This is pom.xml file having the entries of dependency jars and information to build the application .
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cv.hb</groupId>
<artifactId>All_operations</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<artifactId>hibernate-core</artifactId>
<groupId>org.hibernate</groupId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>4.0.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
provided
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.1.0.CR2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
|