[Hibernate] Khắc phục lỗi Unable to insert if column named is keyword, such as DESC

  • 17
  • 0
Vấn đề
Bảng có tên “category” trong database MySQL, chứa cột có tên “DESC”.

SQL:
CREATE TABLE `category` (
  `CATEGORY_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `NAME` varchar(10) NOT NULL,
  `DESC` varchar(255) NOT NULL,
  PRIMARY KEY (`CATEGORY_ID`) USING BTREE
);
File mapping XML của Hibernate
XML:
<hibernate-mapping>
    <class name="com.mkyong.stock.Category" table="category" catalog="mkyongdb">
        ...
        <property name="desc" type="string">
            <column name="DESC" not-null="true" />
        </property>
       ...
    </class>
</hibernate-mapping>
Hoặc Hibernate annotation
Java:
@Column(name = "DESC", nullable = false)
    public String getDesc() {
        return this.desc;
    }
Khi insert dữ liệu vào bảng category, sẽ xuất hiện lỗi sau:
Code:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
   You have an error in your SQL syntax; check the manual...

[Hibernate] Lưu hình ảnh vào database

  • 16
  • 0
Để lưu hình ảnh vào database, cần xác định cột của bảng là kiểu blob trong MySQL hoặc loại nhị phân tương đương trong database khác. Trong Hibernate, có thể khai báo một biến kiểu byte[] để lưu trữ dữ liệu hình ảnh.

Download source code – Hibernate-Image-Example.zip

Đây là 1 prrooject Maven sử dụng Hibernate để lưu hình ảnh vào bảng ‘avatar' của MySQL.

1. Tạo bảng
Táo bảng có tên avatar trong MySQL

SQL:
CREATE TABLE  `mkyong`.`avatar` (
  `AVATAR_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `IMAGE` blob NOT NULL,
  PRIMARY KEY (`AVATAR_ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2. Maven dependency

Thêm dependency Hibernate và MySQL.

pom.xml
XML:
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"...

[Hibernate] Sử dụng các keyword của database trong hibernate

  • 18
  • 0
Trong Hibernate, khi cố lưu đối tượng vào bảng với bất kỳ keyword dành riêng cho database nào dưới dạng tên cột, có thể gặp phải lỗi sau …

Code:
ERROR JDBCExceptionReporter:78 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the
right syntax to use near 'Datadabase reserved keyword....
Keyword “DESC”
Trong MySQL, “DESC” là 1 keyword của database. Hãy xem một số ví dụ để nói về cách sử dụng keyword này trong Hibernate.

File mapping XML của Hibernate
Đây là file mapping XML mặc định cho 1 cột trong bảng, nó sẽ gây ra lỗi JDBCException…

XML:
<property name="desc" type="string" >
    <column name="DESC" length="255" not-null="true" />
</property>
Giải pháp
1. Bao keyword trong dấu [].

XML:
<property name="desc" type="string" >
    <column name="[DESC]" length="255" not-null="true" />
</property>
2. Sử dụng dấu nhấy đơn (‘) kèm...

[Hibenate] Gọi store procedure trong hibernate

  • 17
  • 0
Chào các bạn, trong bài viết này, chúng ta sẽ tìm hiểu về cách gọi store procedure trong hibernate

MySQL store procedure
Đây là 1 store procedure trong MySQL, nó nhận vào 1 tham số là stock code và trả về dữ liệu liên quan đến stock.

SQL:
DELIMITER $$

CREATE PROCEDURE `GetStocks`(int_stockcode varchar(20))
BEGIN
   SELECT * FROM stock where stock_code = int_stockcode;
   END $$

DELIMITER ;
Trong MySQL, có thể gọi bằng keyword call:

SQL:
CALL GetStocks('7277');
Sử dụng Hibernate để gọi store procedure
Trong Hibernate, có 3 cách để gọi store procedure trong database.

1. Native SQL – createSQLQuery
Sử dụng createSQLQuery() để gọi store procedure trực tiếp.

Java:
Query query = session.createSQLQuery(
    "CALL GetStocks(:stockCode)")
    .addEntity(Stock.class)
    .setParameter("stockCode", "7277");

List result = query.list();
for(int i=0; i<result.size(); i++){...

[Hibernate] Cấu hình hiển thị hibernate sql parameter - Log4j

  • 46
  • 0
Vấn đề
Hibernate có tính năng ghi log cơ bản để hiển thị câu SQL được tạo ra với property show_sql trong file cấu hình

Code:
Hibernate: INSERT INTO mkyong.stock_transaction (CHANGE, CLOSE, DATE, OPEN, STOCK_ID, VOLUME)
VALUES (?, ?, ?, ?, ?, ?)
Tuy nhiên, nó không đủ để fix bug, giá trị của các Hibernate SQL parameter bị thiếu.

Giải pháp – Log4j

Yêu cầu sử dụng Log4J để hiển thị giá trị của Hibernate SQL parameter.

1. Cấu hình Log4j trong Hibernate
Theo dõi bài biết Cấu hình Log4j trong Hibernate

2. Thay đổi Log level
Chỉnh sửa file Log4j properties và...

[Hibernate] Cấu hình hiển thị hibernate sql parameter - P6Spy

  • 28
  • 0
Câu hỏi đặt ra
Có nhiều developer đặt ra câu hỏi về giá trị Hibernate SQL parameter. Làm thế nào để hiển thị giá trị của Hibernate SQL parameter được truyền vào database? Hibernate chỉ hiển thị giá trị tham số dưới dạng dấu hỏi (?). Với property show_sql, Hibernate sẽ hiển thị tất cả các câu SQL được tạo ra, nhưng không hiển thị các giá trị SQL parameter.

Lấy ví dụ
Code:
Hibernate: insert into mkyong.stock_transaction (CHANGE, CLOSE, DATE, OPEN, STOCK_ID, VOLUME)
values (?, ?, ?, ?, ?, ?)
Vậy có cách nào để log hoặc hiển thị giá trị SQL paramerter của Hibernate không?

Giải pháp – P6Spy
Vâng, nếu có câu hỏi, có 1 câu trả lời ~

P6Spy là thư viện để ghi log các câu SQL và parameter trước khi truyền vào database. P6Spy là miễn phí, nó sử dụng để...

[Hibernate] Hiển thị SQL của hibernate ra console – show_sql , format_sql và use_sql_comments

  • 44
  • 0
Hibernate có 1 hàm để enable tính năng ghi log tất cả các lệnh SQL được tạo ra tại console. Có thể kích hoạt nó bằng cách tạo 1 property “show_sql” trong file cấu hình Hibernate “hibernate.cfg.xml“. Hàm này tốt cho xử lý sự cố cơ bản và để xem những gì mà Hibernate đang làm phía sau

1. show_sql
Enable ghi log tất cả lệnh SQL ra màn hình console

XML:
<!--hibernate.cfg.xml -->
<property name="show_sql">true</property>
Kết quả
Code:
Hibernate: insert into mkyong.stock_transaction
(CHANGE, CLOSE, DATE, OPEN, STOCK_ID, VOLUME)
values (?, ?, ?, ?, ?, ?)


2. format_sql
Format SQL được hibernate generate ra để dễ đọc hơn, sẽ chiếm nhiều không gian màn hình hơn.

XML:
<!--hibernate.cfg.xml -->
<property name="format_sql">true</property>
Kết quả
Code:
Hibernate:
    insert
    into
        mkyong.stock_transaction...

[Hibernate] Liệt kê các Hibernate SQL Dialect

  • 35
  • 0
Hibernate SQL Dialect sẽ nói cho ứng dụng Hibernate biết nên sử dụng ngôn ngữ SQL nào để giao tiếp với database.

1. DB2
Code:
org.hibernate.dialect.DB2Dialect
2. DB2 AS/400
Code:
org.hibernate.dialect.DB2400Dialect
3. DB2 OS390
Code:
org.hibernate.dialect.DB2390Dialect
4. PostgreSQL
Code:
org.hibernate.dialect.PostgreSQLDialect
5. MySQL
Code:
org.hibernate.dialect.MySQLDialect
6. MySQL with InnoDB
Code:
org.hibernate.dialect.MySQLInnoDBDialect
7. MySQL with MyISAM
Code:
org.hibernate.dialect.MySQLMyISAMDialect
8. Oracle 8
Code:
org.hibernate.dialect.OracleDialect
9. Oracle 9i/10g
Code:
org.hibernate.dialect.Oracle9Dialect
10. Sybase
Code:
org.hibernate.dialect.SybaseDialect
...

[Hibernate] Cách thêm file hibernate XML mapping (hbm.xml) theo cách lập trình

  • 34
  • 0
File mapping XML của Hibernate chứa relationship mapping giữa class Java và table trong database. Chúng thường có tên là “xx.hbm.xml” và khai báo trong file cấu hình Hibernate “hibernate.cfg.xml”.

Ví dụ, file mapping (hbm.xml) được khai báo trong thẻ “mapping”.

XML:
<?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.bytecode.use_reflection_optimizer">false</property>
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyong</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>...

[Hibernate] Cách load file hibernate.cfg.xml từ một thư mục khác

  • 27
  • 0
File cấu hình XML của Hibernate “hibernate.cfg.xml” thường được đặt ở thư mục gốc của project classpath, bên ngoài của bất kì package nào. Nếu cho file cấu hình vào thư mục khác, sẽ gặp lỗi bên dưới:

Code:
Initial SessionFactory creation failed.org.hibernate.HibernateException:
/hibernate.cfg.xml not found

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.mkyong.persistence.HibernateUtil.buildSessionFactory(HibernateUtil.java:25)
    at com.mkyong.persistence.HibernateUtil.<clinit>(HibernateUtil.java:8)
    at com.mkyong.common.App.main(App.java:11)
Caused by: org.hibernate.HibernateException: /hibernate.cfg.xml not found
    at org.hibernate.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:147)
    at org.hibernate.cfg.Configuration.getConfigurationInputStream(Configuration.java:1405)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1427)
    at...

[Hibernate] Maven + (Spring + Hibernate) Annotation + MySql

  • 43
  • 0
Download – Spring-Hibernate-Annotation-Example.zip

Trong bài trước, chúng ta đã sử dụng Maven để tạo Java project đơn giản và sử dụng Hibernate trong Spring framework để thực hiện các thao tác (select, insert, update và delete) tại database MySQL. Trong bài này, ta sẽ biết thêm cách làm điều tương tự bằng annotation Spring và Hibernate.

Yêu cầu tiên quyết
– Cài đặt và cấu hình Maven, MySQL, Eclipse IDE.

Thư viện javaee.jar cần thiết hơn, có thể lấy nó từ j2ee SDK và include thủ công, đây không là phiên bản đầy đủ của javaee.jar đang có trong bất kỳ Maven repoitory nào.

Cấu trúc project sau cùng
Cấu trúc project cuối cùng như sau, nếu mất trong việc tạo cấu trúc thư mực, hãy xem bên dưới...

Maven + Spring + Hibernate + MySql

  • 48
  • 0
Chào các bạn, trong bài viết này, chúng ta sẽ sử dụng Maven để tạo 1 Java project đơn giản và sử dụng Hibernate trong Spring framework để thực hiện các thao tác với dữ liệu (insert, select, update và delete) trong database MySQL.

Cấu trúc project sau cùng
Đây là cấu trúc project, nếu bạn gặp khó khăn trong việc tạo cấu trúc thư mục, hãy xem cấu trúc thư mục dưới đây.

mavan-spring-hibernate-mysql.gif


1. Tạo table
Tạo table ‘stock’ trong database MySQL:

SQL:
CREATE TABLE  `mkyong`.`stock` (
  `STOCK_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `STOCK_CODE` varchar(10) NOT NULL,
  `STOCK_NAME` varchar(20) NOT NULL,
  PRIMARY KEY (`STOCK_ID`) USING BTREE,
  UNIQUE KEY `UNI_STOCK_NAME` (`STOCK_NAME`),
  UNIQUE KEY `UNI_STOCK_ID` (`STOCK_CODE`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
2. Cấu trúc file trong...

[Hibernate] Struts + Spring + Hibernate

  • 52
  • 0
Download source code Struts 1.x + Spring + Hibernate – Struts-Spring-Hibernate-Example.zip

Chào các bạn, trong bài viết này, chúng ta sẽ tạo ứng dụng web quản lí khách hàng đơn giản. Dùng Maven để quản lý project, Struts 1.x là web framework, Spring là dependency injection framework và Hibernate là database ORM framework.

Kiến trúc tích hợp tổng thể thì giống như bên dưới:

Code:
Struts (Web page) <---> Spring DI <--> Hibernate (DAO) <---> Database
Để tích hợp tất cả kỹ thuật với nhau, bạn phải:
  1. Tích hợp Spring với Hibernate với class “LocalSessionFactoryBean" của Spring.
  2. Tích hợp Spring với Struts bằng plug-in có sẵn trong Spring để support Struts là “ContextLoaderPlugIn“.

1. Cấu trúc Project
Đây là cấu trúc sau cùng của project này.
[ATTACH type="full"...​

[Hibernate] Tích hợp Hibernate vào Struts framework

  • 37
  • 0
Chào các bạn, trong bài viết này, chúng ta sẽ cùng tìm hiểu về cách tích hợp Hibernate vào web application được phát triển bằng Apache Struts 1.x.

Download source code – Struts-Hibernate-Example.zip

Các bước tích hợp:
  1. Tạo file Hibernate Struts plug-in để thiết lập Hibernate session factory trong servlet context, và include file này vào file struts-config.xml.
  2. Trong Struts, lấy Hibernate session factory trong servlet context và ra lệnh Hibernate làm bất cứ việc gì bạn muốn.

1. Hibernate Struts Plug-in
Tạo Hibernate Struts Plug-in, lấy Hibernate session factory, đưa nó vào servlet context cho người dùng sau - servlet.getServletContext().setAttribute(KEY_NAME, factory);.

Java:
package com.mkyong.common.plugin;

import java.net.URL;
import javax.servlet.ServletException...

[Hibernate] Sự khác nhau giữa session.get() và session.load()

  • 58
  • 0
Thường xuyên, ta sẽ thấy các Hibernate developer sử dụng kết hợp session.get() và session load(). Bạn có tự hỏi những điểm khác nhau giữa chúng và khi nào nên sử dụng 1 trong 2?

Sự khác nhau giữa session.get() và session.load()
Thực ra, cả 2 hàm được sử dụng để lấy ra 1đối tượng với cơ chế khác nhau, tất cả sẽ được trình bay bên dưới.

1. session.load()
  • Nó thường trả về một “proxy” (1 thuật ngữ của hibernate) mà không cần hit tại database. Trong Hibernate, proxy là 1 đối tượng với giá trị identifier đã cho, property của nó chưa được khởi tạo, nó chỉ giống như một đối tượng giả tạm thời.
  • Nếu không tìm thấy dữ liệu phù hợp, nó sẽ ném ra exception ObjectNotFoundException.

2. session.get()
  • Nó hit database và trả về một đối tượng thật, và đối tượng này đại diện dòng trong cơ sở dữ liệu, không phải poxy.
  • Nếu không tìm thấy dòng nào, nó sẽ trả về...

[Hibernate] fetching strategy

  • 71
  • 0
Hibernate có một vài fetching strategy để tối ưu câu lệnh select được được tạo, để nó có hiệu quả nhất có thể. Fetching strategy được khai báo trong mapping relationship để định nghĩa cách Hibernate lấy các collection và entity iên quan của entity.

Các Fetching Strategy
Có 4 fetching stratery

1. fetch-“join” = Disable lazy loading, thường load tất cả các collection và entity liên quan.
2. fetch-“select” (mặc định) = Lazy load tất cả các collection và entity liên quan.
3. batch-size=”N” = Load ‘N’ collections hoặc entities, *Not record*.
4. fetch-“subselect” = Group collection trong lệnh sub select.

Chi tiết hơn, có thể xem tại Hibernate documentation.

Ví dụ về Fetching strategy
Đây là ví dụ về “one-to-many relationship” để trình bày về fetching strategy. Một stock có liên quan đến nhiều stock daily record.

Ví dụ khai báo fetch strategy trong file XML
XML:
...

[Hibernate] Mutable (class và collection)

  • 83
  • 0
Trong Hibernate, "mutable" mặc định là "true" trong class và collection của nó, nghĩa là class hoặc collection cho phép insert, update và delete. Mặt khác, nếu mutable thay đổi là false, có ý nghĩa khác nhau trong class và colection của nó. Lấy một vài ví dụ để hiểu rõ hơn về nó.

Hibernate one-to-many
Lấy ví dụ one-to-many để trình bày về mutable. Trong file mapping này, một Stock liên qua đến nhiều StockDailyRecord.

XML:
<!-- Stock.hbm.xml -->
...
<hibernate-mapping>
    <class name="com.mkyong.common.Stock" table="stock" >
        <set name="stockDailyRecords" mutable="false" cascade="all"
               inverse="true" lazy="true" table="stock_daily_record">
            <key>
                <column name="STOCK_ID" not-null="true" />
            </key>
            <one-to-many class="com.mkyong.common.StockDailyRecord" />
        </set>...

[Hibernate] dynamic-update attribute

  • 87
  • 0
dynamic-update là gì
dynamic-update attribute cho Hibernate biết, có thêm các property không có sự thay đổi về giá trị vào lệnh SQL UPDATE hay không


Dynamic-update
1. dynamic-update=false

Giá trị mặc định của dynamic-update=false, có nghĩa là thêm cả property không được sửa đổi vào lệnh SQL update của Hibernate.

Ví dụ, lấy ra 1 đối tượng và thử thay đổi giá trị của nó và update lại vào database.

Java:
Query q = session.createQuery("from StockTransaction where tranId = :tranId ");
q.setParameter("tranId", 11);
StockTransaction stockTran = (StockTransaction)q.list().get(0);

stockTran.setVolume(4000000L);
session.update(stockTran);
Hibernate sẽ tự tạo câu lệnh update như bên dưới.

Code:
Hibernate:
    update
        mkyong.stock_transaction
    set
        DATE=?,
        PRICE_CHANGE=?,
        PRICE_CLOSE=?,
        PRICE_OPEN=?,
        STOCK_ID=...

[Hibernate] dynamic-insert attribute

  • 121
  • 2
dynamic-insert là gì
Attribute dynamic-insert cho Hibernate biết liệu có thêm các property có giá trị null vào câu SQL INSERT hay không. Xem vài ví dụ để hiểu rõ hơn về nó.


Ví dụ về dynamic-insert

1. dynamic-insert=false

Giá trị mặc định của dynamic-insert là false, nghĩa là thêm các property có giá trị null vào câu SQL INSERT của Hibernate.

Ví dụ, thử set null cho một số property của object và lưu nó.
Java:
StockTransaction stockTran = new StockTransaction();
//stockTran.setPriceOpen(new Float("1.2"));
//stockTran.setPriceClose(new Float("1.1"));
//stockTran.setPriceChange(new Float("10.0"));
stockTran.setVolume(2000000L);
stockTran.setDate(new Date());
stockTran.setStock(stock);

session.save(stockTran);
Enable Hibernate "show_sql” là true, sẽ thấy lệnh SQL insert bên dưới.

Java:
Hibernate:
    insert
    into
        mkyong.stock_transaction...

[Hibernate] Interceptor - Audit log

  • 69
  • 0
Hibernate có một tính năng mạnh mẽ gọi là ‘interceptor‘ để chặn hoặc hook các event của Hibernate, như hoạt động CRUD. Trong bài viết này, chúng ta sẽ tìm hiểu và cách làm ứng dụng với tính năng audit log bằng cách sử dụng Hibernate interceptor, nó sẽ ghi lại các hoạt động insert, update, delete của Hibernate vào trong cơ sở dữ liệu có tên bảng là ‘auditlog‘.

Hibernate interceptor – audit log


1. Tạo bảng
Tạo 1 bảng ‘auditlog’ để lưu tất cả các hoạt động của ứng dụng.

SQL:
DROP TABLE IF EXISTS `mkyong`.`auditlog`;
CREATE TABLE  `mkyong`.`auditlog` (
  `AUDIT_LOG_ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `ACTION` varchar(100) NOT NULL,
  `DETAIL` text NOT NULL,
  `CREATED_DATE` date NOT NULL,
  `ENTITY_ID` bigint(20) unsigned NOT NULL,
  `ENTITY_NAME` varchar(255) NOT NULL,
  PRIMARY KEY (`AUDIT_LOG_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT...