I vaguely recall learning about derived properties back in one of the SQL sessions, but nothing much afterwards really.So why this write up, well a question about derived properties popped up in one of the interviews I had recently. I mess around with Hibernate a lot, I am not a guru but I know my way around it, but I can't say I have come across a scenario that mandated the usage of derived properties so my answer was, let's just say, not satisfactory.
Well, enough about that. Let's see how it's done then. You got two options; option number one ; use the formula attribute of the property
I' ll just jump straight to code and show you how it's done.
First the xml approach,
<property name="fullName" formula="CONCAT(fName,' ',lName)" /> <property name="idMul" formula="id * 12.0" />
And now how to do it with annotations,
import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import org.hibernate.annotations.Formula; @Entity @Table(name = "person") public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String fName; private String lName; private Date dob; @Formula("id * 12.0") private float idMul; @Formula("CONCAT(fName,' ',lName)") private String fullName;And you can now write your queries based around your derived properties in the following fashion
List<Person> person2 = (List<Person>) session.createQuery("from Person p where p.idMul > 5 and p.id=2").list();
And if you inspect your console you will see the following output,
Hibernate: select person0_.id as id0_, person0_.dob as dob0_, person0_.fName as fName0_, person0_.lName as lName0_, CONCAT(person0_.fName, ' ', person0_.lName) as formula0_, person0_.id * 12.0 as formula1_ from person person0_ where person0_.id * 12.0>5 and person0_.id=2
Now before you close this window and down vote this post, I have to tell you I did this seemingly odd multiplication operation with the 'id' field to demonstrate what can be achieved within a formula annotation.
Although its not clear from the code above, you need to understand that whatever you put inside this annotation or the
List<Person> person2 = (List<Person>) session.createQuery("from Person p where (p.idMul > 5 or p.fullName like '%chi%' ) and p.id=2").list();
Hibernate: select person0_.id as id0_, person0_.dob as dob0_, person0_.fName as fName0_, person0_.lName as lName0_, CONCAT(person0_.fName, ' ', person0_.lName) as formula0_, person0_.id * 12.0 as formula1_ from person person0_ where ( person0_.id * 12.0>5 or CONCAT(person0_.fName,' ',person0_.lName) like '%chi%' ) and person0_.id=2
So you have to be careful about using derived properties in Hibernate.
Interesting post. Did not know of its existenc until now.
ReplyDeleteHI ,
ReplyDeleteYour Post is So Nice and Very good Explanation.
I have a Doubt....
Can i place dynamic values in that "@Formula" query? If Yes How?
i need to calculate using values coming from client and table values,
Kindly reply.
Thanks & Regards
raju
Hello Raju,
ReplyDeleteI believe you can use positional or named parameters.
I am using hibernate template to load the data from DB. I get "invalid column name" error referring to CONCAT keyword. my concat expression look like CONCAT(a,CONCAT(','b)).
ReplyDelete