CUSTOM ENTITY CREATION
We can create entity class of a table
using hibernate and pojo. And it can be used with hibernate query and hibernate
native sql queries.`@Entity` annotation is used to identify the entity class.
Assume that we use hibernate query to
return particular result from table and map the result to entity.
Example :-
we have 2 table named `shop_type` and
`shop`
And we set `shop_type_id` as foreign
key for `shop ` table
table `shop_type`
shop_type_id
|
name
|
1
|
Hotel
|
2
|
M.Market
|
3
|
Textile
|
table `shop`
shop_id
|
shop_type_Id
|
name
|
entry_date
|
1
|
1
|
AVN
|
03/16/12 12:05 AM
|
2
|
1
|
AKN
|
03/16/12 12:10 AM
|
3
|
2
|
Reliance m
|
03/16/12 12:15 AM
|
4
|
3
|
AnimalTXT
|
03/16/12 12:20 AM
|
Assume that we have 2 entity classes
named `Shop` and `ShopType`
and so we have two entity
classes. if we want to select a
particular details from 'shop' table we can simply use our hibernate query
eg:-
hql = "from Shop s where
s.shopId = ?";
Query
query = session.createQuery(hql);
query.setInteger(0,
shopId);
(Shop)(query.uniqueResult());
and when we execute this statement .
Hibernate will include all column of `shop` table in select statement by
default and its a background process doing by hibernate. The reason for this
behavior is only then hibernate can map
this result to corresponding entity class here it is `Shop.class`.
Example for background process is
something like this
select s.shop_id,s.shop_type_id,s.name,s.phone_number from shop s
whee
s.shop_id = 1;
we can also use our native sql query also for
select the result.
Eg :- sql = "select {s.*} from shop s
where s.shop_id = ?";
SQLQuery
query = session.createSQLQuery(sql);
query.addEntity("s",
Shop.class);
query.setInteger(0,
shopId);
(Shop)(query.uniqueResult());
In this case also we need to select
full column in our select statement.'{}'
symbol
is used when selecting all
columns and this tells the hibernate
that all fields are selected.
Until now we select all column from
table using select statements and mapped it to corresponding entity. And we
find that without this way we can't map the result to entity.
Good news is that there is a way to
select specified columns from a table using hibernate native sql quires.
using .addScalar property we
can achieve this.
Eg:-
sql = "select s.name as sname from
shop s where s.shop_id = ?";
SQLQuery countQuery =
session.createSQLQuery(hql).addScalar("sname",Hibernate.STRING)
return ((Object[])
countQuery.uniqueResult());
But using this properties we can't
map the result in to entity class and it only return objects .
Until now the result set column names
are assumed to be the same as the column names specified in the mapping
document. This can be problematic for SQL queries which join multiple tables,
since the same column names may appear in more than one table. Assume that if
we have a situation and we want to join two table and select only 3 columns .
So we can use addScalar property
but if we need to select 10 columns then
addScalar will not be a proper way to accomplish this task.
Because using lots of addScalar properties will complicate our task and traveling of data
will be more difficult. Also if we pass this result to velocity there will be
difficulties.
So in this case we can use custom entity like classes for mapping our
join query result. Using this way we can reduce complexity and it behave like
an entity class object. We can use it anywhere we like. To doing this we need
to create a java class.
This example will give you an clear
idea.
We have a sql query
sql = SELECT
s.`name`,st.name,,s.entry_date FROM shop
s JOIN shop_type st ON(s.type_id = st.shop_type_id);
This will return
name
|
name
|
entry_date
|
AVN
|
Hotel
|
03/16/12 12:05 AM
|
AKN
|
Hotel
|
03/16/12 12:10 AM
|
Reliance m
|
M.Market
|
03/16/12 12:15 AM
|
Animal TXT
|
Textile
|
03/16/12 12:20 AM
|
And i am trying to map the result in to an
custom entity to doing this we need to
create a class just like entity class . And this class must have variables. And
1.Variable name must be same as
column names in our select statement
2.must include getter and setter
methods for that variables .
3.Data type of variable also same as
in table .
Here data type of column entry_date
is Date in database and so variable `entryDate`.We can see that here some
column have same names.[1st
and 2nd column have same name]and this will make some problems in
our entity because there is an ambiguity. To solve this we can use alias in our
query and so the column name will change
eg :- SELECT s.`name` as
shopName,st.name as typeName,s.entry_date as entryDate FROM shop s JOIN shop_type st ON(s.type_id =
st.shop_type_id);
This will return
shopName
|
typeName
|
entryDate
|
AVN
|
hotel
|
03/16/12 12:05 AM
|
AKN
|
hotel
|
03/16/12 12:10 AM
|
Reliance m
|
M.market
|
03/16/12 12:15 AM
|
Animal TXT
|
textile
|
03/16/12 12:20 AM
|
So we can see that now 3 column have
different names 'shopName' and 'typeName',entryDate
respectively. Use this names for creating variable for class `ShopView`
.Now we can create our custom entity class .
Created Class
public class ShopView {
private String shopName;
private String typeName;
private Date entryDate
public String getShopName () {
return shopName;
}
public void setShopName(String shopName) {
this. shopName = shopName;
}
public String get TypeName () {
return typeName;
}
public void setTypeName (String typeName) {
this. typeName = typeName;
}
public Date getEntryDate() {
return entryDate;
}
public void setEntryDate(Date entryDate) {
this.entryDate = entryDate;
}
}
ShopView is our new custom entity class for
mapping our result.
For mapping our result to our newly
created class we need to use query.setResultTransformer(Transformers.aliasToBean(ClassName.class));
method
For our Example we can use like this.
Sql ="SELECT s.`name` as
shopName,st.name as typeName,s.entry_date as entryDate FROM shop s JOIN shop_type st ON(s.type_id =
st.shop_type_id)";
SQLQuery query =
session.createSQLQuery(sql);
query.setResultTransformer(Transformers.aliasToBean(ShopView
.class));
pager.setResult(query.list());
A ResultTransformer is a nice and
simple interface that allows you to transform any Criteria result element.
The above query will
return a list which has been instantiated and injected
into its
corresponding properties or fields in ShopView class. Using this way we can
map our result into
any class. This way is suitable in case of sql views. Means we
can create custom
view entities for our needs.
Use this object in
velocity page example.
Assume that we passed
the result to velocity and we set
the name as `shopDetailsList`
then we can use the list in velocity as
#foreach($shopObj in
$shopDetailsList)
$ shopObj
.shopName
$ shopObj
.typeName
#end