What is the difference between transient, a persistent and detached object in Hibernate?


Both save() and persist() are used to insert a new entity in the database. You're calling them on entities that already exist in the database. So they do nothing.
The main difference between them is that save() is Hibernate-proprietary, whereas persist() is a standard JPA method. Additionally, save() is guaranteed to assign and return an ID for the entity, whereas persist() is not.
update() is used to attach a detached entity to the session.
saveOrUpdate() is used to either save or update an entity depending on the state (new or detached) of the entity.
Note that you don't need to call any method of the session to modify an attached entity: doing

User user1 = (User) session.load(User.class, Integer.valueOf(1));
user1.setCompany("Company3");
merge() is a standard JPA method. saveOrUpdate() and update() are proprietary Hibernate methods. In general, you should use merge(). update() is used to take adetached entity and attach it to the session. merge() doesn't attach an object to the session. It copies the state of an detached entity to the attached entity which has the same ID.
tutorialspoint.com hibernate

1. Hibernate CRUD 1
            String queryString = "from FeeInvoice fee where fee.shopId = ?";
            Query queryObject = session.createQuery(queryString);
            queryObject.setParameter(0, shopId);
            FeeInvoice feeInvoice = (FeeInvoice)queryObject.uniqueResult();
Note: Nếu câu truy vấn là "from FeeInvoice where shopId = ?" thì khi thực hiện câu lệnh sẽ bị sai.

            Query hqlQuery = session.createQuery("from ImportEmployee as so where so.id.ownCode = ? and so.id.stOwnCode=? and so.id.status=1");
            hqlQuery.setParameter(0, "1230000100XX_ABC");
            hqlQuery.setParameter(1, "ABCDEFT_T11_DDLLC1");
            hqlQuery.setMaxResults(1);
            persistentInstance = (ImportEmployee) hqlQuery.uniqueResult();

2. Hibernate CRUD 2
         Transaction t = session.beginTransaction();
         Employee member = (Employee) session.get(Employee.class, 1); // select
         member.setName("Name1");
         session.update(member); // update
         session.save(member); // save new data
         Query query = session.createQuery("from Employee");
        List<?> list = query.list();
         long result = (Long) session.createCriteria(Employee.class).setProjection(Projections.rowCount()).uniqueResult();
         session.delete(member);
         tx.commit();

        String hql = "DELETE FROM Employee "  + "WHERE id = :empID";
        Query query = session.createQuery(hql);
        query.setParameter("empID", 10);
        int result = query.executeUpdate();
        System.out.println("affected Rows: " + result);

        Query query = session.createQuery("delete Category where id = :ID");
        query.setParameter("ID", new Long(10));
        int result = query.executeUpdate();
Tham khảo: http: hibernate-annotations-tutorial

3. Hibernate CRUD 3
                FeeInvoice testFeeInvoice
                        = (FeeInvoice) session.get(FeeInvoice.class, feeInvoice.getId());
                testFeeInvoice.updateFeeInvoice(updateBillShopForm);
                session.update(testFeeInvoice);

4. Hibernate CRUD 4
feeInvoice = new FeeInvoice(updateBillShopForm);
session.save(feeInvoice);

5. Native Hibernate SQL 1
Ví dụ:  
            String hqlUpdate = "update fee_invoice c set c.NAME = :newName, c.INVOICE_NO = :invoiceNo, c.INVOICE_DATE = :invoiceDate where c.SHOP_ID = :shopId";
            Query query = session.createSQLQuery(hqlUpdate);
            query.setString("newName", feeInvoice.getName())
            .setString("invoiceNo", feeInvoice.getInvoiceNo())
            .setDate("invoiceDate", feeInvoice.getInvoiceDate())
            .setLong("shopId", feeInvoice.getShopId())
            .executeUpdate();

nếu dùng JDBC thì đoạn mã trên tương ứng như sau:       
            ResultSet rs  = null;
            PreparedStatement ps = null;
            Connection conn = session.connection();
            ps.setString(1, feeInvoice.getName());
            ps = conn.prepareStatement(hqlUpdate);
            ps.setString(2, feeInvoice.getInvoiceNo());
            ps.setDate(3, new java.sql.Date(feeInvoice.getInvoiceDate().getTime()));
            ps.setLong(4, feeInvoice.getShopId());
            ps.executeUpdate();

6. Hibernate Secure Usage
/* Positional parameter in HQL */
Query hqlQuery = session.createQuery("from Orders as orders where orders.id = ?");
List results = hqlQuery.setString(0, "123-ADB-567-QTWYTFDL").list();
/* named parameter in HQL */
Query hqlQuery = session.createQuery("from Employees as emp where emp.incentive > :incentive");
List results = hqlQuery.setLong("incentive", new Long(10000)).list();
/* named parameter list in HQL */
List items = new ArrayList(); 
items.add("book"); items.add("clock"); items.add("ink");
List results = session.createQuery("from Cart as cart where cart.item in (:itemList)").setParameterList("itemList", items).list();
/* JavaBean in HQL */
Query hqlQuery = session.createQuery("from Books as books where book.name = :name and book.author = :author");
List results = hqlQuery.setProperties(javaBean).list(); //assumes javaBean has getName() & getAuthor() methods.
/* Native-SQL */
Query sqlQuery = session.createSQLQuery("Select * from Books where author = ?");
List results = sqlQuery.setString(0, "Charles Dickens").list();
Tham khảo: JBoss Query Native

public void arryEmployeesEntity( ){
       Session session = factory.openSession();
       Transaction tx = null;
       
       try {
          tx = session.beginTransaction();
          String sql = "SELECT id, first_name, salary FROM EMPLOYEE";
          SQLQuery query = session.createSQLQuery(sql);
          List<Object[]> rows = query.list();

          for(Object[] row : rows){
             System.out.print("ID: " + row[0].toString()); 
             System.out.print("  First Name: " + row[1].toString()); 
             System.out.println("  Salary: " + row[2].toString()); 
          }
          tx.commit();
       } catch (HibernateException e) {
          if (tx!=null) tx.rollback();
          e.printStackTrace(); 
       } finally {
          session.close(); 
       }
  }
public void listEmployeesFirstName( ){
       Session session = factory.openSession();
       Transaction tx = null;
       
       try {
          tx = session.beginTransaction();
          List lstSalary = new ArrayList();
          lstSalary.add(2000L);
          lstSalary.add(5000L);
          String sql = "SELECT first_name FROM EMPLOYEE where salary in (:pSalary)";
          SQLQuery query = (SQLQuery) session.createSQLQuery(sql).setParameterList("pSalary", lstSalary);
          List data = query.list();
          System.out.println("############values of 'first_name' columm by salary >");
          for(Object object : data) {
             String row = object != null ? object.toString() : "";
             System.out.println("First Name: " + row); 
          }
          tx.commit();
       } catch (HibernateException e) {
          if (tx!=null) tx.rollback();
          e.printStackTrace(); 
       } finally {
          session.close(); 
       }
    }
connection = getSession().connection();
List<Object[]> retResult = (List<Object[]>) session.createSQLQuery(sql_goods_entity_query)
        .addScalar("longTermAssetId", Hibernate.LONG)
        .addScalar("longTermAssetIdCounter", Hibernate.LONG)
        .setParameterList("pLstLongTermId", pLstLongTermId).list();
if (retResult != null) {
    for (Object[] row : retResult) {
        Long longTermAssetIdKey = row[0] != null ? Long.parseLong(row[0].toString()) : null;
        Long goodsCounterVal = row[1] != null ? Long.parseLong(row[1].toString()) : null;
        Long hanOverCounter = pMapLongTermAssetIdCountGoodsHandOver.get(longTermAssetIdKey);
        if (longTermAssetIdKey != null) {
            if (goodsCounterVal != null && goodsCounterVal.equals(hanOverCounter)) {
                mapLongTermAssetIdCounterResult.put(longTermAssetIdKey, 1L);
            } else {
                mapLongTermAssetIdCounterResult.put(longTermAssetIdKey, 0L);
            }
        }
    }
}
7. Hibernate Generator classes
The <generator> subelement of id used to generate the unique identifier for the objects of persistent class (Hibernate generator element generates the primary key for new record). There are many generator classes defined in the Hibernate Framework.
All the generator classes implements the org.hibernate.id.IdentifierGenerator interface. The application programmer may create one's own generator classes by implementing the IdentifierGenerator interface. Hibernate framework provides many built-in generator classes:
  • assigned
  • increment
  • sequence
  • hilo
  • native
  • identity
  • seqhilo
  • uuid
  • guid
  • select
  • foreign
  • sequence-identity

assigned generator:
assigned is a shortcut name given for the Assigned class.
Assigned class returns same id set by the programmer to hibernate and hibernate will store an object with that Id in database.
If we don’t map the generator class for id in hbm.xml file then by default assigned generator is mapped to it.
1
2
3
4
5
<id name="studentId" column="sid">/>
OR
<id name="studentId" column="sid">
            <generator class="assigned"/>
</id>
On the above example both syntaxes are same for the assigned generator.
8. Hibernate Criteria

The Hibernate Session interface provides createCriteria() method which can be used to create a Criteria object that returns instances of the persistence object's class when your application executes a criteria query. Ví dụ, truy vấn 1 thực thể với complex key:
ImportEmployee testData = new ImportEmployee(new EmployeeId("900004600123_ABC", "USER_CODE_TTC", (byte) 1));
Criteria criteria = this.getSession().createCriteria(ImportEmployee.class);
criteria.add(Restrictions.eq("id", testData.getId()));
//criteria.add(Restrictions.idEq(testData.getId()));
ImportEmployee testEntiyDb = (ImportEmployee) criteria.uniqueResult();

            FeeInvoice feeInvoice = null;
            Criteria crit = session.createCriteria(FeeInvoice.class);
            crit.add(Restrictions.eq("shopId", shopId));
            crit.setMaxResults(1);
            List<FeeInvoice> results = crit.list();            
            if (results != null && results.size() > 0) {
                feeInvoice = results.get(0);
            }

            return feeInvoice;
- Declarative mapping
-- Map classes to tables; fields to columns; relationships to foreign keys and join tables
- CRUD API
-- E.g. Hibernate Session, JPA EntityManager
- Query language
-- Retrieve objects satisfying search criteria
- Transaction management
-- Manual transaction management
-- Rarely call directly – used by Spring
- Detached objects
-- Detach persistent objects from the DB
-- Eliminates use of DTOs
-- Supports edit-style use cases
- Lazy loading
-- Provide the illusion that objects are in memory
-- But loading all objects would be inefficient
⇒ load an object when it is first accessed
- Eager loading
-- Loading objects one at a time can be inefficient
-- ⇒ load multiple objects per-select statement
- Caching
-- Database often the performance bottleneck
-- ⇒ cache objects in memory whenever you can
-- Easy for readonly objects
-- Optimistic locking and cache invalidation for changing objects

10. hibernate.cfg.xml
- Oracle:
<hibernate-configuration>
    <session-factory>
        <property name="hbm2ddl.auto">update</property>
        <!--<property name="hbm2ddl.auto">create</property>-->
        <property name="dialect">org.hibernate.dialect.OracleDialect</property>
        <property name="connection.url">jdbc:oracle:thin:@10.30.7.12:1521:DDT1</property>
        <property name="connection.username">ANORACLEUSER</property>
        <property name="connection.password">ANORACLEUSER2016ac</property>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <mapping resource="com/javatexample/database/domain/employee.hbm.xml"/>
    </session-factory>
</hibernate-configuration>
- MySql
<?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.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sakila</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
    <mapping resource="dvdrental/FilmActor.hbm.xml"/>
    <mapping resource="dvdrental/Language.hbm.xml"/>
    <mapping resource="dvdrental/Film.hbm.xml"/>
    <mapping resource="dvdrental/Category.hbm.xml"/>
    <mapping resource="dvdrental/Actor.hbm.xml"/>
    <mapping resource="dvdrental/FilmCategory.hbm.xml"/>
    
<mapping class="test.Person"/>

  </session-factory>
</hibernate-configuration>


10. Lấy tạm đổi tượng connection cho việc test dữ liệu 
public Connection init() throws ServletException {
        Connection connection = null;
        try {
//            Class.forName("org.gjt.mm.mysql.Driver");
//            String dbURL = "jdbc:mysql://localhost/struts2db";
//            String username = "root";
//            String password = "root123";
            Class.forName("oracle.jdbc.driver.OracleDriver");
            String dbURL = "jdbc:oracle:thin:@11.31.7.12:1521:DDVV1";
            String username = "SLEPORT";
            String password = "se@@2016";
            connection = DriverManager.getConnection(
                    dbURL, username, password);
        } catch (ClassNotFoundException e) {
            System.out.println("Database driver not found.");
        } catch (SQLException e) {
            System.out.println(
                    "Error opening the db connection: "
                    + e.getMessage());
        }
        return connection;
    }

11. hibernate.hbm2dll.auto 
hibernate.hbm2ddl.auto Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.
e.g. validate | update | create | create-drop
So the list of possible options are,
  • validate: validate the schema, makes no changes to the database.
  • update: update the schema.
  • create: creates the schema, destroying previous data. The data previously present (if there) in the schema is lost
  • create-drop: drop the schema at the end of the session. The schema is not dropped on closing the session. It drops only on closing the SessionFactory.
These options seem intended to be developers tools and not to facilitate any production level databases, you may want to have a look at the following question; Hibernate: hbm2ddl.auto=update in production?