Rabu, 13 Oktober 2010

Hibernate Self Join - Test Java Code

MenuHow to Do Self Join Many-To-Many Mapping In Hibernate
Hibernate Self Join - Create DB Tables
Hibernate Self Join - Create Java Class
Hibernate Self Join - Create Hibernate Configuration
Hibernate Self Join - Test Java Code
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:

Keyword keyword1 = (Keyword)manager.getKeywordById(243);
Keyword keyword2 = (Keyword)manager.getKeywordById(250);
Keyword keyword3 = (Keyword)manager.getKeywordById(260);
Set children=new HashSet();
children.add(keyword2);
children.add(keyword3);
keyword1.setChildren(children);
manager.createOrUpdate(keyword1);


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!

◀ Create Hibernate Configuration

Hibernate Self Join - Create Hibernate Configuration

MenuHow to Do Self Join Many-To-Many Mapping In Hibernate
Hibernate Self Join - Create DB Tables
Hibernate Self Join - Create Java Class
Hibernate Self Join - Create Hibernate Configuration
Hibernate Self Join - Test Java Code
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?

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping default-lazy="false">
<class name="entity.Keyword" table="keyword">
<id name="keywordId" column="keyword_id">
<generator class="increment" />
</id>
<property name="title" column="title" />
<property name="body" column="body" />
<property name="lastModifiedTime" column="last_modified_time" />
<property name="createTime" column="create_time" />
<set name="parents" table="keyword_to_keyword" cascade="none" lazy="false">
<key column="child_id"/>
<many-to-many column="parent_id" class="entity.Keyword" />
</set>
<set name="children" table="keyword_to_keyword" cascade="none" lazy="false">
<key column="parent_id"/>
<many-to-many column="child_id" class="entity.Keyword" />
</set>
</class>
</hibernate-mapping>


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!

◀ Create Java ClassTest Java Code ▶

Hibernate Self Join - Create Java Class

MenuHow to Do Self Join Many-To-Many Mapping In Hibernate
Hibernate Self Join - Create DB Tables
Hibernate Self Join - Create Java Class
Hibernate Self Join - Create Hibernate Configuration
Hibernate Self Join - Test Java Code
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?

package entity;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Keyword{

@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!

◀ Create DB TablesCreate Hibernate Configuration ▶

Hibernate Self Join - Create Database Tables

MenuHow to Do Self Join Many-To-Many Mapping In Hibernate
Hibernate Self Join - Create Database Tables
Hibernate Self Join - Create Java Class
Hibernate Self Join - Create Hibernate Configuration
Hibernate Self Join - Test Java Code
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,

primary key(keyword_to_keyword_id),
unique key mffl_keyword_to_keyword_ids (parent_id,child_id),
foreign key (parent_id) references keyword(keyword_id),
foreign key (child_id) references keyword(keyword_id)
) engine=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;


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!

◀ Self Join Mapping in Hibernate Tutorial HomeCreate Java Class ▶

How to Do Self Join Many-To-Many Mapping In Hibernate

MenuHow to Do Self Join Many-To-Many Mapping In Hibernate
Hibernate Self Join - Create DB Tables
Hibernate Self Join - Create Java Class
Hibernate Self Join - Create Hibernate Configuration
Hibernate Self Join - Test Java Code
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.

Let's first create a database table schema in MySQL! Questions? Let me know!

Create DB Tables ▶

How To Get All Posts of a Blog Via Blogger API

Q: I'd like to get all posts of my blog hosted on Google's Blogger via their Java API. How?

I have a blog that has less than 1000 entries and I'd like to get them all programmatically via Blogger Java API, and I setMaxResults(1000) of my Query object thinking that it would return all entries of my blog. But it DID NOT!! How frustrating! And Blogger API or their documentation or tutorial says nothing about it I find it unreasonable; so I have to address this issue.

Solution
After some tweaking I found that if you setMaxResults() to more than 500 you only get back 500 Entry objects, each representing a feed specified by a Feed URL. Then what do you do? Simple. Get 500 entries at a time and get as many times as you need to retrieve all posts of your blog (or feeds of any Google service). This can be done because the results returned are put in the post date order with more recent entries first. Each time you grab a batch of entries you specify an incremental start index via setStartIndex(). So code wise you'd specify your Blogger's blog's URL, use it to create a Query, set the Query's properties and use BloggerService to retriev the Feed and its list of entries. Here's some code to help you out.

public Collection getAllPostsViaApi() throws ServiceException, IOException {
// Request the feed
URL feedUrl = new URL("http://www.blogger.com/feeds/[your-blog-id]/posts/default");

Collection allEntries = new ArrayList();
Query myQuery = new Query(feedUrl);
int startIndex=1; // one based
BloggerService service = new BloggerService("service-name");
while(true){
myQuery.setStartIndex(startIndex);
myQuery.setMaxResults(500);
Feed resultFeed = service.getFeed(myQuery, Feed.class);
List thisBatch = resultFeed.getEntries();
if(thisBatch.isEmpty()){
break;
}else{
allEntries.addAll(thisBatch);
startIndex+=thisBatch.size();
}
}
return allEntries;
}


Questions? Let me know! It should be straightforward but if there's anything unclear leave me a comment and I'll get back to you as soon as I can!
 
support by: infomediaku.com