So we've created a database table to embody the concept of a Keyword, a table to join a Keyword to itself, the actual Java class that embodies the Keyword, the corresponding Hibernate configuration. Now you should be able to test our code.
'manager' is our manager whose job is to do CRUD (create, read, update, delete) operations on a Hibernate aware entity. Suppose we already have Keywords with keyword_id 243, 250, 260. Here's how we add a couple of keywords to another keyword as its children:
With any luck you'll run the code without an error and see that the corresponding rows created in the database correctly. Congratulations! Questions? Let me know! Otherwise enjoying Java and Hibernate!
Now that we have database tables and Java class down, we have to tell Hibernate that we are doing self joins on Keyword. We can do this with XML configuration or Annotation. Here's the XML configuration. You can easily adapt it to Annotation if you are using Annotation. Questions?
We simply tell Hibernate that keyword_to_keyword has a column 'parent_id' that refers to another Keyword, joined by keyword_id column, as the parent. and it has a column 'child_id' that refers to another Keyword as the child. Since a keyword can have many parents and/or children this is a many-to-many mapping! Questions? Let me know!
Now we have the database tables to represent our entity Keyword and to join it to itself, let's create a Java class to embody a Keyword and its self-join characteristic. Note that you need to have two Sets of Keywords as the instance variables: one as its parents and one as its children. Then create simple setters and getters of each property. Easy right? Questions?
@Id @GeneratedValue private Integer keywordId; private String title; private String body; private Set<keyword> parents = new HashSet<keyword>(); private Set<keyword> children = new HashSet<keyword>(); private Date lastModifiedTime; private Date createTime; public Integer getKeywordId() { return keywordId; } public void setKeywordId(Integer keywordId) { this.keywordId = keywordId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public Set<keyword> getParents() { return parents; } public void setParents(Set<keyword> parents) { this.parents = parents; } public Set<keyword> getChildren() { return children; } public void setChildren(Set<keyword> children) { this.children = children; } public Date getLastModifiedTime() { return lastModifiedTime; } public void setLastModifiedTime(Date lastModifiedTime) { this.lastModifiedTime = lastModifiedTime; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } }
Let's create the necessary Hibernate configurations to let Hibernate know all about our little plan to have Keyword able to join itself! Questions? Let me know!
So our entity is Keyword, and each Keyword can have a set of Keywords as its parents and a set of keywords as its children. This means this mapping is many-to-many and we need a join table to represent the relationships! DON'T WORRY; a join table is simply a table that keeps track of who are whose parents and who are whose children. Questions?
# table 'keyword' that's supposed to have a set of children and parents joined by keyword_to_keyword create table keyword( keyword_id int not null auto_increment, title varchar(255) not null, body text not null, last_modified_time timestamp not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, create_time timestamp not null,
primary key (keyword_id) ) engine=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
# self join table for keyword create table keyword_to_keyword( keyword_to_keyword_id int not null auto_increment, parent_id int not null, child_id int not null, last_modified_time timestamp not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, create_time timestamp not null,
As you can see 'keyword_to_keyword' is the table for keyword to join itself. The parent_id in keyword_to_keyword specifies the parent and child_id specifies the child. I included last_modified_time and create_time columns because it's my habit to know when a row was created and when it's last updated, but you don't have to if you don't want to. Questions? Let me know!
Now that we have our table in database let's create the corresponding Java class!
Q: I'd like to realize the relationship that a table has a set of parents and a set of children which are all members of that table. How do I do that with Java and Hibernate?
Hibernate has been out there for a long time but I am surprised I couldn't find online a comprehensive tutorial on realizing self join relationships in Hibernate. I am sure many out there are wondering the same thing; so I decided to write a post to address this issue.
First of all here are the exact things I'd like to achieve:
* Create a Java entity called Keyword. A Keyword has a title and a body. * Each Keyword can have a set of keywords as its parents and a set of keywords as its children, and I can easily set and get a keyword's parents and children in Java which when persisted the relationships will be recorded in the database.
Hibernate is an incredible open source Object-relational mapping (or ORM, O/RM, O/R mapping) tool in Java. Suppose you have many database tables that are related to each other in some ways. If you want to query them with raw SQLs it'd be a nightmare (lots of joins, criteria, etc.). But with Hibernate you simply define the mappings in XML configuration files and you'll be able to retrieve the data as Java objects and be able to manipulate them as such
Download the latest Hibernate distribution package from Hibernate's download website. Mine is hibernate-distribution-3.5.3-Final-dist.zip. If the latest version is not this one it's fine. Try it and Let me know if you encounter any issues.. Unzip it and drop the following jars in your java's extension directory (mine is C:\Program Files (x86)\Java\jdk1.6.0_20\jre\lib\ext\). If you don't know why we are doing this consult How Java Recognizes Where Things Are.
* hibernate-distribution-3.5.3-Final\hibernate3.jar * hibernate-distribution-3.5.3-Final\lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar * every jar in hibernate-distribution-3.5.3-Final\lib\required\
Download the latest slf4j package at http://www.slf4j.org/download.html. At the time of writing it is slf4j-1.6.0.zip. Unzip it and drop slf4j-api-1.6.0.jar in java's extension folder; then delete slf4j-api-1.5.8.jar in the same folder if you see it.
Download and drop mysql-connector-java-5.1.13-bin.jar in java's extension directory.
Now you should be able to use Hibernate! Let me give you a sample setup. Create hibernate.cfg.xml in C:\ and put the following in it. Hibernate automatically reads hibernate.cfg.xml from the directory of the Java class you are running. Questions?
<?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="connection.url">jdbc:mysql://localhost:3306/mffl</property> <property name="connection.username">root</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- <property name="connection.password">iamroot</property>--> <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> <!-- thread is the short name for org.hibernate.context.ThreadLocalSessionContext and let Hibernate bind the session automatically to the thread --> <property name="current_session_context_class">thread</property> <!-- this will show us all sql statements --> <property name="hibernate.show_sql">false</property>
From this configuration file Hibernate learns about underlying properties of the database and where to look for mapping files (specified by mapping tag). Here's the corresponding automate.hbm.xml in C:\config\: Questions?
You should be able to create the corresponding database tables brand, store, and brand_to_store. Then create the corresponding Java files Brand.java and Store.java. Questions? Let me know!
This is not an uncommon request for someone who wants to run a web server with an underlying database, backed by a server side programming language, assisted by several important one off or periodic tasks - me. Okay if it's just me then it might have been uncommon, but I have gone through a lot to finally have all these tools set up, so I'd like to share my experiences with you.
First of all I'd like to tell you why I am doing this. I'd like my web server (Apache) to serve dynamic content (PHP) driven by my database (MySQL) and dynamic content driven by one off or regular tasks (Java) with an easy way to manipulate my database content via Java objects (Hibernate), and I'd like to develop my Java code in a user friendly IDE (Eclipse). Last but not least I'd like to do ALL of these FREE, and they certainly are
Let's get right down to it! Click on the next section.