At line 2 changed 1 line. |
This is a tutorial to show how to create and manage Hibernate relationships within [AppFuse]. This tutorial was written for AppFuse 1.8 and the AppGen pieces may not work with previous versions. |
This is a tutorial to show how to create and manage Hibernate relationships within [AppFuse]. This tutorial was written using AppFuse 1.8.2. All of the code for this tutorial is downloadable at [http://static.appfuse.org/downloads/appfuse-hr.zip]. |
At line 6 added 2 lines. |
%%note __NOTE:__ Copying the Java code in this tutorials [doesn't work in Firefox|http://raibledesigns.com/page/rd?anchor=java2html_plugin_for_jspwiki_causes]. A workaround is to CTRL+Click (Command+Click on OS X) the code block and then copy it.%% |
|
At line 7 changed 2 lines. |
* [1] Create Weblog.java, Entry.java and add XDoclet tags |
* [2] [[Many-to-One] Create a new Category object and modify Entry.java to use it |
* [1] Create Weblog.java, Entry.java and Category.java domain objects |
* [2] [[Many-to-Many] A Weblogs can have many Users, a User can have many Weblogs |
At line 10 changed 4 lines. |
* [4] [[Many-to-Many] Shared Weblogs are possible for multiple Users |
* [5] [[DAO Stuff] Setting up Unit Tests and DAO classes for basic CRUD |
* [6] Lazy-Loading Issues |
* [7] Managing relationships and indexed properties in the UI |
* [4] [[Many-to-One] A Category object can be assigned to many entries |
At line 17 changed 1 line. |
In this example, the ''Weblog'' object is used to indentify a person's blog. This class has the following properties: |
The ''Weblog'' object is used to indentify a person's blog. This class has the following properties: |
At line 20 removed 1 line. |
* username |
At line 32 changed 1 line. |
The first thing you need to do in this tutorial is these two object to persist. Create both a ''Weblog.java'' class and an ''Entry.java'' class (in the src/dao/**/model directory). The necessary XDoclet tags for these entities is included on the ''getter'' method's javadoc. |
Below is a class diagram of these two objects, as well as the others you'll create in this tutorial. |
At line 34 changed 2 lines. |
* [View Weblog.java|Weblog.java] |
* [View Entry.java|Entry.java] |
[ER-Diagram.jpg] |
At line 37 changed 1 line. |
;:''Rather than fill up this tutorial with large blocks of Java code, the necessary files are attached and linked to. Small code snippets are used where appropriate.'' |
The first thing you need to do in this tutorial is these two object to persist. Create a __Weblog.java__ class and an __Entry.java__ class (in the src/dao/**/model directory). The necessary XDoclet tags for these entities is included on the ''getter'' method's javadoc. You can download these files using the links below. Note that javadocs have been eliminated for brevity. |
At line 39 changed 1 line. |
%%note __Tip:__ The equals(), hashCode() and toString() methods can be generated by your IDE. If you're using Eclipse, get the [Commonclipse|http://commonclipse.sourceforge.net/] plugin. For IDEA, the first two are built into the "Generate..." dialog, and toString() is a plugin you can download.%% |
* [Download Weblog.java|Weblog.java] |
* [Download Entry.java|Entry.java] |
At line 41 changed 1 line. |
!![[Many-to-One] Create a new Category object and modify Entry.java to use it [#2] |
;:''Rather than fill up this tutorial with large blocks of Java code, the necessary files are attached and linked to. Small code snippets are used where appropriate. You should be able to easily download the files by right-clicking on them and selecting "Save Target As...".'' |
At line 43 changed 1 line. |
A category object will act as an entity for persisting category information about weblog entries. A category object will consist of an id (primary key), category name, and a description. Each category can have many entries. |
Create a __Category.java__ object to act as an entity for persisting category information about weblog entries. Each category can have many entries. This class contains the following properties: |
At line 45 changed 1 line. |
* [View Category.java|Category.java] |
* categoryId |
* name |
* description |
At line 47 changed 1 line. |
The many-to-one relationship between entry and category can be established using XDoclet tags. Hibernate relationships can typically be established on either side of the relationship or as a bi-directional one as well. For our purposes,this relationship will be maintained by an extra property and collection held by Entry. The list of possible categories for a weblog entry will eventually be represented as a drop-down on the UI. |
* [Download Category.java|Category.java] |
At line 49 changed 1 line. |
[{Java2HtmlPlugin |
!Configure Spring |
At line 51 changed 3 lines. |
|
private Long categoryId; |
private Category category; |
Add the 3 new mapping files (that will be generated) to the "sessionFactory" bean's ''mappingResources'' property in __src/org/appfuse/dao/hibernate/applicationContext-hibernate.xml__. |
At line 55 removed 29 lines. |
/** |
* @hibernate.many-to-one insert="false" update="false" cascade="none" |
* column="category_id" outer-join="true" |
*/ |
public Category getCategory() { |
return category; |
} |
|
public void setCategory(Category category) { |
this.category = category; |
} |
|
/** |
* @hibernate.property column="category_id" |
*/ |
public Long getCategoryId() { |
return categoryId; |
} |
|
public void setCategoryId(Long categoryId) { |
this.categoryId = categoryId; |
} |
|
}] |
|
!![[One-to-Many] A Weblog object can have many Entries [#3] |
|
Modify the Weblog object and Entry object to represent the multiplicity of a weblog that can have many entries. This relationship is set on the Weblog class using a list. XDoclet tags are used to establish this relationship using a __bag__ as the Hibernate collection type. |
|
At line 86 changed 16 lines. |
private List entries; |
|
/** |
* @return Returns the entries. |
* |
* @hibernate.bag name="entries" lazy="false" inverse="true" cascade="delete" |
* @hibernate.collection-key column="weblog_id" |
* @hibernate.collection-one-to-many class="org.appfuse.model.Entry" |
*/ |
public List getEntries() { |
return entries; |
} |
|
public void setEntries(List entries) { |
this.entries = entries; |
} |
<property name="mappingResources"> |
<list> |
<value>org/appfuse/model/Role.hbm.xml</value> |
<value>org/appfuse/model/User.hbm.xml</value> |
<value>org/appfuse/model/Weblog.hbm.xml</value> |
<value>org/appfuse/model/Entry.hbm.xml</value> |
<value>org/appfuse/model/Category.hbm.xml</value> |
</list> |
</property> |
At line 104 changed 1 line. |
The Entry class is modified slightly to provide a placeholder for the relationships between Weblog and Entry. |
!![[Many-to-Many] A Weblogs can have many Users, a User can have many Weblogs [#2] |
At line 106 changed 1 line. |
[{Java2HtmlPlugin |
A Weblog can have many Users. Basically the idea is of a shared weblog that is a place where many users can express themselves about a particular topic of interest. For this bit of functionality the User object will be modified to have a many-to-many relationship with Weblog. |
At line 108 changed 1 line. |
private Long weblogId; |
Add the following ''users'' property and accessor methods to __Weblog.java__. |
At line 110 removed 18 lines. |
/** |
* @hibernate.property column="weblog_id" |
*/ |
public Long getWeblogId() { |
return weblogId; |
} |
|
public void setWeblogId(Long weblogId) { |
this.weblogId = weblogId; |
} |
}] |
|
!![[Many-to-Many] [#4] |
|
The Weblog system that we are developing allows one additional bit of functionality. A particular Weblog can have many Users. Basically the idea is of a shared weblog that is a place where many users can express themselves about a particular topic of interest. For this bit of functionality the User object will be modified to have a many-to-many relationship with Weblog. |
|
Add the following ''users'' property and accessor methods to ''Weblog.java''. |
|
At line 130 changed 1 line. |
private Set users = new HashSet(); |
private List users = new ArrayList(); |
At line 133 changed 1 line. |
* @hibernate.set table="weblog_user" cascade="none" lazy="false" |
* @hibernate.bag table="weblog_user" cascade="save-update" lazy="true" |
At line 137 changed 1 line. |
public Set getUsers() { |
public List getUsers() { |
At line 145 changed 1 line. |
public void setUsers(Set users) { |
public void setUsers(List users) { |
At line 94 added 2 lines. |
%%note __NOTE:__ The reason a java.util.List is used instead of a java.util.Set is because this is because [Sets aren't supported for indexed properties in Struts|http://www.mail-archive.com/[email protected]/msg26289.html].%% |
|
At line 152 changed 1 line. |
In addition to allow navigation from a Weblog object to their list of users, you need to add a Set of Weblogs to the User object - allowing that path of navigation as well. Modify ''User.java'' to add a ''weblogs'' Set and accessor methods. |
To allow navigation from a User objec to a list of Weblogs, you need to add a List of Weblogs to the User object. Modify ''User.java'' to add a ''weblogs'' List and accessor methods. |
At line 156 changed 3 lines. |
protected Set weblogs; |
|
public Set getWeblogs() { |
protected List weblogs; |
|
/** |
* @hibernate.bag table="weblog_user" cascade="save-update" lazy="true" |
* @hibernate.collection-key column="username" |
* @hibernate.collection-many-to-many class="org.appfuse.model.Weblog" column="weblog_id" |
*/ |
public List getWeblogs() { |
At line 162 changed 1 line. |
public void setWeblogs(Set weblogs) { |
public void setWeblogs(List weblogs) { |
At line 167 changed 1 line. |
!![[DAO Stuff] [#5] |
!Test it! |
At line 169 changed 1 line. |
In order to test that all of this works, you need to create some test classes, add some sample data, develop some DAO interfaces, and create hibernate DAO classes. |
Create a unit test so you can verify that everything actually works. Create a __WeblogDaoTest__ class in your test/dao/**/dao directory. This file should extend GenericDaoTest. If you're using anything less than AppFuse 1.9, you may have to modify GenericDAOTest's "dao" variable so its __protected__ instead of private. Copy the code below into this test: |
At line 171 removed 6 lines. |
!!Test Classes |
|
!WeblogDaoTest |
|
Let's start with ''WeblogDaoTest.java'' class. Create this class in ''test/dao/**/dao'' and fill it with the following code. |
|
At line 182 removed 1 line. |
import java.util.List; |
At line 184 removed 1 line. |
import org.appfuse.model.Weblog; |
At line 186 changed 1 line. |
import org.springframework.dao.DataAccessException; |
import org.appfuse.model.Weblog; |
At line 188 changed 6 lines. |
public class WeblogDaoTest extends BaseDaoTestCase { |
|
private WeblogDAO wldao = null; |
private Weblog weblog = null; |
private UserDAO udao = null; |
private User user = null; |
public class WeblogDaoTest extends GenericDAOTest { |
At line 195 changed 29 lines. |
protected void setUp() throws Exception { |
super.setUp(); |
wldao = (WeblogDAO) ctx.getBean("weblogDAO"); |
udao = (UserDAO) ctx.getBean("userDAO"); |
} |
|
protected void tearDown() throws Exception { |
super.tearDown(); |
wldao = null; |
} |
|
public void testGetWeblog() throws Exception { |
weblog = wldao.getWeblog(new Long(1)); |
|
assertNotNull(weblog); |
assertEquals(2, weblog.getUsers().size()); |
} |
|
public void testUpdateWeblog() throws Exception { |
weblog = wldao.getWeblog(new Long(2)); |
weblog.setBlogTitle("Testing Update Weblog"); |
wldao.saveWeblog(weblog); |
assertEquals("Testing Update Weblog", weblog.getBlogTitle()); |
} |
|
public void testAddWeblogUser() throws Exception { |
weblog = wldao.getWeblog(new Long(2)); |
|
assertEquals(1, weblog.getUsers().size()); |
public void testWeblogAndUsers() throws Exception { |
Weblog w = new Weblog(); |
w.setBlogTitle("My New Weblog"); |
w.setDateCreated(new Date()); |
At line 225 changed 3 lines. |
user = udao.getUser("tomcat"); |
weblog.addUser(user); |
wldao.saveWeblog(weblog); |
// add it to the database |
dao.saveObject(w); |
At line 229 changed 1 line. |
assertEquals(2, weblog.getUsers().size()); |
w = (Weblog) dao.getObject(Weblog.class, w.getWeblogId()); |
At line 231 changed 5 lines. |
// add the same user twice - should result in no additional user |
weblog.addUser(user); |
wldao.saveWeblog(weblog); |
|
assertEquals("more than 2 of the same users", 2, weblog.getUsers().size()); |
assertTrue(w.getUsers().isEmpty()); |
At line 237 changed 11 lines. |
weblog.getUsers().remove(user); |
wldao.saveWeblog(weblog); |
|
assertEquals(1, weblog.getUsers().size()); |
} |
|
public void testAddAndRemoveWeblog() throws Exception { |
weblog = new Weblog(); |
weblog.setBlogTitle("A new test for adding and then deleting a weblog"); |
weblog.setDateCreated(new Date(2005-04-17)); |
weblog.setUsername("Cartman"); |
// add a user |
User u = (User) dao.getObject(User.class, "mraible"); |
w.addUser(u); |
At line 249 changed 1 line. |
wldao.saveWeblog(weblog); |
dao.saveObject(w); |
At line 251 changed 2 lines. |
assertNotNull(weblog.getBlogTitle()); |
assertEquals("Cartman", weblog.getUsername()); |
w = (Weblog) dao.getObject(Weblog.class, w.getWeblogId()); |
At line 254 changed 1 line. |
wldao.removeWeblog(weblog.getWeblogId()); |
assertTrue(w.getUsers().size() == 1); |
At line 256 changed 11 lines. |
try { |
weblog = wldao.getWeblog(weblog.getWeblogId()); |
fail("saveWeblog didn't throw DataAccessException"); |
} catch (DataAccessException d) { |
assertNotNull(d); |
} |
} |
|
public void testGetEntries() throws Exception { |
List list = wldao.getEntries(new Long(1)); |
assertTrue(list.size() > 0); |
// remove the user |
w.setUsers(null); |
dao.saveObject(w); |
At line 159 added 3 lines. |
w = (Weblog) dao.getObject(Weblog.class, w.getWeblogId()); |
|
assertNull(w.getUsers()); |
At line 269 removed 1 line. |
|
At line 273 changed 1 line. |
!EntryDaoTest |
Make sure you run __ant setup-db__ before running __ant test-dao -Dtestcase=UserDAO__. When running the test, you'll probably get a ''LazyInitializationException''. To solve this, change BaseDaoTestCase to extend Spring's [AbstractTransactionalDataSourceSpringContextTests|http://www.springframework.org/docs/api/org/springframework/test/AbstractTransactionalDataSourceSpringContextTests.html] if it doesn't already. In additional, you'll need to make a few changes to the existing tests so all the tests pass. [Here is a patch|LazyDaoTests.diff]. At a minimum, you'll need to fix BaseDAOTestCase and GenericDAOTest (onSetUp() -> onSetupBeforeTransaction()). |
At line 275 changed 1 line. |
Now, create an ''EntryDaoTest.java'' class. Again, create this class in ''test/dao/**/dao'' and fill it with the following code. |
Because the WeblogDaoTest is now extending AbstractTransactionalDataSourceSpringContextTests (ATDSSCT), there is a "jdbcTemplate" variable you can use to do additional querying. For instance, you could add the following at the end of your ''testWeblogAndUsers()'' method: |
At line 279 changed 1 line. |
package org.appfuse.dao; |
String qry = "select count(*) from weblog_user where username = 'mraible' " + |
" and weblog_id = " + w.getWeblogId(); |
assertEquals(0, jdbcTemplate.queryForInt(qry)); |
}] |
At line 281 changed 1 line. |
import java.sql.Timestamp; |
!![[One-to-Many] A Weblog object can have many Entries [#3] |
At line 283 changed 2 lines. |
import org.appfuse.model.Entry; |
import org.springframework.dao.DataAccessException; |
Now you'll modify the __Weblog__ object and __Entry__ object to represent the multiplicity of a weblog that can have many entries. This relationship is set on the Weblog class using a java.util.List. XDoclet tags are used to establish this relationship using a __bag__ as the Hibernate collection type. Add the following code to your __Weblog.java__ class. |
At line 286 changed 17 lines. |
public class EntryDaoTest extends BaseDaoTestCase { |
|
private EntryDAO edao = null; |
private Entry entry = null; |
|
protected void setUp() throws Exception { |
super.setUp(); |
edao = (EntryDAO) ctx.getBean("entryDAO"); |
} |
|
protected void tearDown() throws Exception { |
super.tearDown(); |
edao = null; |
} |
|
public void testGetEntry() throws Exception { |
entry = edao.getEntry(new Long(1)); |
[{Java2HtmlPlugin |
At line 304 changed 19 lines. |
assertNotNull(entry); |
assertEquals("Testing", entry.getText()); |
} |
|
public void testUpdateEntry() throws Exception { |
entry = edao.getEntry(new Long(2)); |
entry.setText("Testing update entry"); |
entry.setCategoryId(new Long(2)); |
edao.saveEntry(entry); |
|
assertEquals("Testing update entry", entry.getText()); |
} |
|
public void testAddAndRemoveEntry() throws Exception { |
entry = new Entry(); |
entry.setText("Testing add a new entry"); |
entry.setTimeCreated(new Timestamp(2004-04-02)); |
entry.setCategoryId(new Long(3)); |
entry.setWeblogId(new Long(1)); |
private List entries; |
At line 324 changed 15 lines. |
|
edao.saveEntry(entry); |
|
assertNotNull(entry.getText()); |
assertEquals("Testing add a new entry", entry.getText()); |
|
edao.removeEntry(entry.getEntryId()); |
|
try { |
entry = edao.getEntry(entry.getEntryId()); |
fail("saveEntry didn't throw DataAccessException"); |
} catch (DataAccessException d) { |
assertNotNull(d); |
} |
|
/** |
* @return Returns the entries. |
* |
* @hibernate.bag name="entries" lazy="false" cascade="all" |
* @hibernate.collection-key column="weblog_id" |
* @hibernate.collection-one-to-many class="org.appfuse.model.Entry" |
*/ |
public List getEntries() { |
return entries; |
At line 341 changed 2 lines. |
} |
|
public void setEntries(List entries) { |
this.entries = entries; |
} |
At line 345 changed 1 line. |
!CategoryDaoTest |
Modify the __Entry__ class is so it contains a foreign key to its parent __Weblog__ class. |
At line 347 removed 2 lines. |
Next, create an ''CategoryDaoTest.java'' class in ''test/dao/**/dao''. |
|
At line 351 changed 1 line. |
package org.appfuse.dao; |
private Long weblogId; |
At line 353 changed 11 lines. |
import org.appfuse.model.Category; |
import org.springframework.dao.DataAccessException; |
|
public class CategoryDaoTest extends BaseDaoTestCase { |
|
private CategoryDAO catdao = null; |
private Category category = null; |
|
protected void setUp() throws Exception { |
super.setUp(); |
catdao = (CategoryDAO) ctx.getBean("categoryDAO"); |
/** |
* @hibernate.property column="weblog_id" |
*/ |
public Long getWeblogId() { |
return weblogId; |
At line 365 removed 8 lines. |
|
protected void tearDown() throws Exception { |
super.tearDown(); |
catdao = null; |
} |
|
public void testGetCategory() throws Exception { |
category = catdao.getCategory(new Long(1)); |
At line 374 changed 2 lines. |
assertNotNull(category); |
assertEquals("Struts v. Spring MVC", category.getCategoryName()); |
public void setWeblogId(Long weblogId) { |
this.weblogId = weblogId; |
At line 377 removed 32 lines. |
|
public void testUpdateCategory() throws Exception { |
category = catdao.getCategory(new Long(2)); |
category.setCategoryName("Testing update category"); |
catdao.saveCategory(category); |
|
assertEquals("Testing update category", category.getCategoryName()); |
} |
|
public void testAddAndRemoveCategory() throws Exception { |
category = new Category(); |
category.setCategoryName("Spaceman Biff"); |
category.setCategoryDescription("Paying homage to Calvin's alter ego!"); |
|
catdao.saveCategory(category); |
|
assertNotNull(category.getCategoryDescription()); |
assertEquals("Spaceman Biff", category.getCategoryName()); |
|
catdao.removeCategory(category.getCategoryId()); |
|
try { |
category = catdao.getCategory(category.getCategoryId()); |
fail("saveCategory didn't throw DataAccessException"); |
} catch (DataAccessException d) { |
assertNotNull(d); |
} |
|
} |
|
} |
|
At line 411 changed 1 line. |
All of these tests rely on some sample data, so add the following XML to __metadata/sql/sample-data.xml__. |
At this point, you could add an additional test method to WeblogDaoTest to test that this relationship works. Of course, you'll need to run __ant setup-db__ to make sure your database knows about the relationship. |
At line 413 changed 86 lines. |
<div style="color: blue !important; margin-left: 50px"> |
{{{ |
<table name='weblog'> |
<column>weblog_id</column> |
<column>blog_title</column> |
<column>date_created</column> |
<column>username</column> |
<row> |
<value>1</value> |
<value><![CDATA[Sponge Bob is Cool]]></value> |
<value>2004-03-31</value> |
<value>tomcat</value> |
</row> |
<row> |
<value>2</value> |
<value><![CDATA[Java Development = Fun]]></value> |
<value>2005-01-05</value> |
<value>mraible</value> |
</row> |
</table> |
<table name='weblog_user'> |
<column>weblog_id</column> |
<column>username</column> |
<row> |
<value>1</value> |
<value>tomcat</value> |
</row> |
<row> |
<value>1</value> |
<value>mraible</value> |
</row> |
<row> |
<value>2</value> |
<value>mraible</value> |
</row> |
</table> |
<table name='category'> |
<column>category_id</column> |
<column>category_name</column> |
<column>category_description</column> |
<row> |
<value>1</value> |
<value><![CDATA[Struts v. Spring MVC]]></value> |
<value><![CDATA[Comparing implementations of the MVC Design Pattern]]></value> |
</row> |
<row> |
<value>2</value> |
<value><![CDATA[Cycling Notes]]></value> |
<value><![CDATA[All about cycling in the US.]]></value> |
</row> |
<row> |
<value>3</value> |
<value><![CDATA[Cyclocross]]></value> |
<value><![CDATA[Bog Trotters Unite!]]></value> |
</row> |
</table> |
<table name='entry'> |
<column>entry_id</column> |
<column>entry_text</column> |
<column>time_created</column> |
<column>weblog_id</column> |
<column>category_id</column> |
<row> |
<value>1</value> |
<value><![CDATA[Testing]]></value> |
<value>2005-04-11</value> |
<value>1</value> |
<value>1</value> |
</row> |
<row> |
<value>2</value> |
<value><![CDATA[Test Value]]></value> |
<value>2005-04-12</value> |
<value>1</value> |
<value>1</value> |
</row> |
<row> |
<value>3</value> |
<value><![CDATA[Test Value 3]]></value> |
<value>2005-04-12</value> |
<value>2</value> |
<value>3</value> |
</row> |
</table> |
}}} |
</div> |
!![[Many-to-One] A Category object can be assigned to many entries [#4] |
At line 500 changed 1 line. |
Before any of these tests will compile, you need to create the DAO interface and implementation. |
The ''many-to-one'' relationship between __Category__ and __Entry__ can be established using XDoclet tags. Hibernate relationships can be established on either side of the relationship or bi-directionally. For this tutorial, this relationship is maintained by a __categoryId__ property and a __Category__ object in __Entry__. The list of possible categories for a weblog entry will eventually be represented as a drop-down on the UI. Add the following code to your __Entry.java__ class. Notice that the relationship to __Category__ has ''insert="false" update="false"''. This is because the object is read-only. This can be useful for displaying a category's name on the UI when you're viewing an Entry. |
At line 502 removed 2 lines. |
Create a ''WeblogDAO.java'' interface in src/dao/**/dao: |
|
At line 506 changed 1 line. |
package org.appfuse.dao; |
private Long categoryId; |
private Category category; |
At line 508 changed 35 lines. |
import java.util.List; |
import org.appfuse.model.Weblog; |
|
public interface WeblogDAO extends Dao{ |
public Weblog getWeblog(Long weblogId); |
public List getWeblogs(Weblog weblog); |
public void saveWeblog(Weblog weblog); |
public void removeWeblog(Long weblogId); |
} |
}] |
|
|
Then create the Hibernate implementation of this interface in the src/dao/**/dao/hibernate directory. |
|
[{Java2HtmlPlugin |
|
package org.appfuse.dao.hibernate; |
|
import java.util.List; |
|
import org.appfuse.dao.WeblogDAO; |
import org.appfuse.model.Weblog; |
import org.springframework.orm.ObjectRetrievalFailureException; |
|
public class WeblogDAOHibernate extends BaseDaoHibernate implements WeblogDAO { |
|
public Weblog getWeblog(Long weblogId) { |
Weblog weblog = (Weblog) getHibernateTemplate().get(Weblog.class, weblogId); |
|
if (weblog == null) { |
log.warn("uh oh, weblog '" + weblogId + "' not found..."); |
throw new ObjectRetrievalFailureException(Weblog.class, weblogId); |
} |
|
return weblog; |
/** |
* @hibernate.many-to-one insert="false" update="false" cascade="none" |
* column="category_id" outer-join="true" |
*/ |
public Category getCategory() { |
return category; |
At line 545 changed 2 lines. |
public List getWeblogs(Weblog weblog) { |
return getHibernateTemplate().find("from Weblog wl order by upper(wl.blogTitle)"); |
public void setCategory(Category category) { |
this.category = category; |
At line 549 changed 2 lines. |
public void saveWeblog(final Weblog weblog) { |
getHibernateTemplate().saveOrUpdate(weblog); |
/** |
* @hibernate.property column="category_id" |
*/ |
public Long getCategoryId() { |
return categoryId; |
At line 553 changed 2 lines. |
public void removeWeblog(Long weblogId) { |
getHibernateTemplate().delete(getWeblog(weblogId)); |
public void setCategoryId(Long categoryId) { |
this.categoryId = categoryId; |
At line 556 removed 1 line. |
} |
At line 559 changed 1 line. |
!Configure Spring for WeblogDAO |
After making these changes, your __WeblogDaoTest__ should still pass. Verify it does by running __ant setup-db test-dao -Dtestcase=Weblog__. |
At line 561 changed 1 line. |
Modifications need to be made in applicationContext-hibernate.xml for the 3 new entities you created in this tutorial. |
''__Yeah baby, Yeah!__'' |
%%(color: green) |
BUILD SUCCESSFUL\\ |
Total time: 24 seconds |
%% |
At line 563 changed 1 line. |
[{Java2HtmlPlugin |
Before working on the UI, it's helpful to have some sample data so you don't have to do manual data entry. Add the following XML to the bottom of __metadata/sql/sample-data.xml__. |
At line 565 changed 11 lines. |
<property name="mappingResources"> |
<list> |
<value>org/appfuse/model/Role.hbm.xml</value> |
<value>org/appfuse/model/User.hbm.xml</value> |
<value>org/appfuse/model/UserCookie.hbm.xml</value> |
<value>org/appfuse/model/Weblog.hbm.xml</value> |
<value>org/appfuse/model/Entry.hbm.xml</value> |
<value>org/appfuse/model/Category.hbm.xml</value> |
</list> |
</property> |
}] |
<div style="color: blue !important; margin-left: 50px"> |
{{{ |
<table name='weblog'> |
<column>weblog_id</column> |
<column>blog_title</column> |
<column>date_created</column> |
<row> |
<value>1</value> |
<value><![CDATA[Sponge Bob is Cool]]></value> |
<value>2004-03-31</value> |
</row> |
<row> |
<value>2</value> |
<value><![CDATA[Java Development = Fun]]></value> |
<value>2005-01-05</value> |
</row> |
</table> |
<table name='weblog_user'> |
<column>weblog_id</column> |
<column>username</column> |
<row> |
<value>1</value> |
<value>tomcat</value> |
</row> |
<row> |
<value>1</value> |
<value>mraible</value> |
</row> |
<row> |
<value>2</value> |
<value>mraible</value> |
</row> |
</table> |
<table name='category'> |
<column>category_id</column> |
<column>name</column> |
<column>description</column> |
<row> |
<value>1</value> |
<value><![CDATA[Struts vs. Spring MVC]]></value> |
<value><![CDATA[Comparing implementations of the MVC Design Pattern]]></value> |
</row> |
<row> |
<value>2</value> |
<value><![CDATA[Cycling Notes]]></value> |
<value><![CDATA[All about cycling in the US.]]></value> |
</row> |
<row> |
<value>3</value> |
<value><![CDATA[Cyclocross]]></value> |
<value><![CDATA[Bog Trotters Unite!]]></value> |
</row> |
</table> |
<table name='entry'> |
<column>entry_id</column> |
<column>entry_text</column> |
<column>time_created</column> |
<column>weblog_id</column> |
<column>category_id</column> |
<row> |
<value>1</value> |
<value><![CDATA[Testing]]></value> |
<value>2005-04-11 01:02:03.4</value> |
<value>1</value> |
<value>1</value> |
</row> |
<row> |
<value>2</value> |
<value><![CDATA[Test Value]]></value> |
<value>2005-04-12 01:02:03.4</value> |
<value>1</value> |
<value>1</value> |
</row> |
<row> |
<value>3</value> |
<value><![CDATA[Test Value 3]]></value> |
<value>2005-04-12 01:02:03.4</value> |
<value>2</value> |
<value>3</value> |
</row> |
</table> |
}}} |
</div> |
At line 348 added 1 line. |
---- |
At line 578 changed 16 lines. |
Also, you need to add the "weblogDAO" bean definition. |
|
[{Java2HtmlPlugin |
|
<!-- WeblogDAO: Hibernate implementation --> |
<bean id="weblogDAO" class="org.appfuse.dao.hibernate.WeblogDAOHibernate"> |
<property name="sessionFactory"><ref local="sessionFactory"/></property> |
</bean> |
}] |
|
|
After making these changes, you should be able to run __ant test-dao -Dtestcase=WeblogDAO__. All of the tests should pass successfully. |
|
!!Lazy-Loading Issues [#6] |
|
!!Managing relationships and indexed properties in the UI [#7] |
''Next Up:'' __Part II:__ [Create Weblog UI|HibernateRelationshipsUI] - Creating a UI to manage the relationships created in this tutorial. |