<?xml version="1.0"?>
<!-- RSS generated by Radio UserLand v8.0.8 on Tue, 28 Oct 2003 11:58:26 GMT -->
<rss version="2.0">
	<channel>
		<title>Dwight Shih: Software</title>
		<link>http://radio.weblogs.com/0118153/categories/software/</link>
		<description>Content Management and Software Development</description>
		<language>en-us</language>
		<copyright>Copyright 2003 Dwight Shih</copyright>
		<lastBuildDate>Tue, 28 Oct 2003 11:58:26 GMT</lastBuildDate>
		<docs>http://backend.userland.com/rss</docs>
		<generator>Radio UserLand v8.0.8</generator>
		<managingEditor>http://radio.xmlstoragesystem.com/rcsPublic/mailto?usernum=0118153</managingEditor>
		<webMaster>http://radio.xmlstoragesystem.com/rcsPublic/mailto?usernum=0118153</webMaster>
		<skipHours>
			<hour>23</hour>
			<hour>0</hour>
			<hour>1</hour>
			<hour>2</hour>
			<hour>3</hour>
			<hour>22</hour>
			<hour>20</hour>
			<hour>4</hour>
			</skipHours>
		<cloud domain="radio.xmlstoragesystem.com" port="80" path="/RPC2" registerProcedure="xmlStorageSystem.rssPleaseNotify" protocol="xml-rpc"/>
		<ttl>60</ttl>
		<item>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/10/28.html#a645</link>
			<description>&lt;p&gt;If you&apos;re reading this, then please update your links.
The new home is &lt;a href=&quot;http://www.ideoplex.com/blog/topic/software/&quot;&gt;http://www.ideoplex.com/blog/topic/software/&lt;/a&gt; with a new
&lt;a href=&quot;http://www.ideoplex.com/blog/topic/software/rss.xml&quot;&gt;rss feed&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;PS I could use some google juice at the new site.&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/10/28.html#a645</guid>
			<pubDate>Tue, 28 Oct 2003 11:58:19 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=645</comments>
			</item>
		<item>
			<title>The lights are On</title>
			<link>http://www.ideoplex.com/blog/2003/10/03.html#a637</link>
			<description>&lt;p&gt;The lights are on at &lt;a href=&quot;http://www.ideoplex.com/blog/2003/10/03.html#a637&quot;&gt;my new digs&lt;/a&gt;.
Unfortunately, I don&apos;t know how to implement http redirects from the Userland Radio Community Server.
Please update your links to the new location.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/10/03.html#a637</guid>
			<pubDate>Fri, 03 Oct 2003 13:00:40 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=637&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F10%2F03.html%23a637</comments>
			</item>
		<item>
			<title>Going Dark</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/10/01.html#a636</link>
			<description>&lt;p&gt;Take the First Step will be dormant for a few days.
I&apos;m in the process of moving to my own domain
and
will be posting infrequently until the process is complete.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/10/01.html#a636</guid>
			<pubDate>Wed, 01 Oct 2003 13:50:35 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=636&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F10%2F01.html%23a636</comments>
			</item>
		<item>
			<title>I&apos;d buy Radio Userland Again</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/09/27.html#a626</link>
			<description>&lt;p&gt;Mark Beaty also asks &lt;a href=&quot;http://radiocomments2.userland.com/comments?u=118153&amp;p=445&amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2Fcategories%2Fsports%2F2003%2F08%2F03.html%23a445&quot;&gt;whether Radio Userland is worth $39.95&lt;/a&gt;
&amp;ndash; I think so.
The primary contenders for hosted weblogs are &lt;a href=&quot;http://www.userland.com/&quot;&gt;Userland&lt;/a&gt;,
&lt;a href=&quot;http://www.typepad.com/&quot;&gt;TypePad&lt;/a&gt; and
&lt;a href=&quot;http://www.blogger.com/&quot;&gt;Blogger&lt;/a&gt;.
The lowest cost TypePad option is $49.50 per year,
the free Blogger weblog doesn&apos;t provide RSS,
and &lt;a href=&quot;http://new.blogger.com/feature_giveaway/pro_email.pyra&quot;&gt;Blogger Pro is no longer available&lt;/a&gt;.
At $39.95 per year (for continued support and hosting),
Radio Userland has an attractive feature/cost ratio.
&lt;/p&gt;
&lt;p&gt;The real question is whether you prefer smart client/dumb server
or dumb client/smart server?
I like having a lightweight desktop CMS,
so I like Radio Userland &amp;ndash; your mileage may vary.
Both Userland and TypePad offer a free 30-day trial.
My advice is to try them out before making a decision.
&lt;/p&gt;
&lt;p&gt;In fact, I&apos;m willing to pay Userland more.
I&apos;d pay for my own domain name.
And I&apos;d also pay to be on a faster server
&amp;ndash; especially for referrer statistics.
Since I don&apos;t have that option,
I plan to move to my own hosted space in the near future.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/09/27.html#a626</guid>
			<pubDate>Sat, 27 Sep 2003 23:02:39 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=626&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F09%2F27.html%23a626</comments>
			</item>
		<item>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/26.html#a512</link>
			<description>&lt;p&gt;&lt;b&gt;Mea Culpa:&lt;/b&gt; I was taking another look at the Hibernate documentation in preparation for playing with persistent subclasses when I came across the mutable property.
And I realized that I had said that Hibernate shouldn&apos;t be used for immutable classes when I meant to say that you need to be wary of comparing object references from different Hibernate sessions.
I&apos;ve corrected &lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/2003/08/18.html#a487&quot;&gt;Hibernate Prototyping with the BeanShell&lt;/a&gt;.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/26.html#a512</guid>
			<pubDate>Tue, 26 Aug 2003 22:58:27 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=512&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F26.html%23a512</comments>
			</item>
		<item>
			<title>IT Still a Great Career</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/25.html#a509</link>
			<description>&lt;p&gt;Nothing is better than getting paid to do something that you would do anyway.
There aren&apos;t many professions that you can say that about,
but I think that&apos;s still true of IT.
IT lives in a junction of logical thought and creative expression
that stretches and challenges your mind like few other things can.
&lt;/p&gt;
&lt;p&gt;Yes, IT is under attack from
outsourcing, foreign competition and a poor economy.
But what isn&apos;t?
And while outsourcing support looks good on the bottom line,
it&apos;s often more of a cost shift than a savings
&amp;ndash;
fine when shifting costs to your customers
but not so good when shifting costs to your business units.
&lt;/p&gt;
&lt;p&gt;So I think that it would be a mistake for Tim Bray to
&lt;a href=&quot;http://www.tbray.org/ongoing/When/200x/2003/08/21/HiringTech&quot; title=&quot;Wrong Profession?&quot;&gt;guide his son away from this profession&lt;/a&gt;.
He should make sure that he has exposure to other careers.
But if the kid has the knack
(he certainly has the genes),
then I wouldn&apos;t fight it.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/25.html#a509</guid>
			<pubDate>Mon, 25 Aug 2003 23:33:38 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=509&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F25.html%23a509</comments>
			</item>
		<item>
			<title>RSS, Email and 1-to-1 Marketing</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/21.html#a499</link>
			<description>&lt;p&gt;To my way of thinking,
RSS is most effective as a broadcast medium
while
email is most effective as a narrowcast medium.
When we&apos;re broadcasting,
we&apos;re trying to generate buzz &amp;ndash; an awareness of who we are, what we do,
and why we&apos;re good people.
We&apos;re interested in the aggregate effect:
how many readers,
reader retention,
and the like.
But when we&apos;re narrowcasting,
we&apos;re trying to elicit a specific reader action.
Our focus is on the individual response.
&lt;/p&gt;
&lt;p&gt;In 1-to-1 Marketing,
we want to take members of our broadcast audience and convert them to narrowcast
and eventually customer.
The evolution from broadcast to narrowcast to customer
necessitates a loss of anonymity.
We develop more information about individuals so that we can target
information and proposals for them.
&lt;/p&gt;
&lt;p&gt;If RSS is to play a significant role in that evolution,
then it needs to distinguish between readers
and become part of the process of learning about individual readers.
Returning to yesterday&apos;s request for
&lt;a href=&quot;http://radio.weblogs.com/0118153/2003/08/20.html#a495&quot; title=&quot;RSS User IDs&quot;&gt;a standard block of [anonymous] IDs&lt;/a&gt;,
many people won&apos;t want to be a part of that process.
It&apos;s best to recognize that and provide a mechanism
that works within your overall marketing effort.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/21.html#a499</guid>
			<pubDate>Thu, 21 Aug 2003 12:47:25 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=499&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F21.html%23a499</comments>
			</item>
		<item>
			<title>RSS User IDs</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/20.html#a495</link>
			<description>&lt;p&gt;Well, I guess I wasn&apos;t paying close attention to the feedback on Tim Bray&apos;s &lt;a href=&quot;http://www.tbray.org/ongoing/When/200x/2003/05/25/Subscribers&quot; title=&quot;Counting Subscribers&quot;&gt;counting RSS subscribers&lt;/a&gt; &amp;ndash; Greg Reinacker describes a &lt;a href=&quot;http://www.rassoc.com/gregr/weblog/archive.aspx?post=641&quot;&gt;method for automatically assigning RSS user IDs&lt;/a&gt; (and Derek Scruggs&apos; work on &lt;a href=&quot;http://www.escalan.com/blog/2003_05_25_index_archive.php#95042198&quot;&gt;counting RSS subscribers&lt;/a&gt;). I have my misgivings, but it looks promising.
&lt;/p&gt;
&lt;p&gt;Derek has concerns about aggregator support
for HTTP 301 redirects and ETag headers.
I&apos;d like to add aggregator support for user IDs to the list.
It&apos;s the wild west in RSS and aggregators right now and people will be hopping around
for a while.
So we need to easily transfer user IDs from aggregator to aggregator.
And we need to balance that against the ability to refer others to RSS feeds
without piggy backing on existing user IDs.
&lt;/p&gt;
&lt;p&gt;Plus, I think that people will always want a safety net of anonymity.
So it might be nice to reserve a standard block of IDs for that purpose
&amp;ndash;
an aggregator could then be configured to randomly use an ID from that block
for a given feed.
&lt;/p&gt;
&lt;p&gt;I still think that email marketing has a lot of life left in it.
But maybe RSS is ready to take on more of the load than I had thought.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/20.html#a495</guid>
			<pubDate>Wed, 20 Aug 2003 11:47:36 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=495&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F20.html%23a495</comments>
			</item>
		<item>
			<title>Marketing by RSS</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/19.html#a489</link>
			<description>&lt;p&gt;I love RSS as much as anyone else, but we don&apos;t do anyone any favors when we refuse to take off the rose-colored sunglasses. Chris Pirillo &lt;a href=&quot;http://rss.lockergnome.com/archives/opinion/006658.phtml&quot;&gt;throws some brickbats at an RSS doubter&lt;/a&gt;, but I happen to agree with the doubter on several points:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can&apos;t reliably measure exposure via RSS.&lt;/li&gt;
&lt;li&gt;You can&apos;t control how RSS is displayed.&lt;/li&gt;
&lt;li&gt;RSS doesn&apos;t build a user database.&lt;/li&gt;
&lt;li&gt;RSS is difficult to customize - as a response driver - the way email is.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tim Bray brought up the issue of &lt;a href=&quot;http://www.tbray.org/ongoing/When/200x/2003/06/01/Subscribers2&quot; title=&quot;Subscribers Redux&quot;&gt;RSS Subscriber Counting&lt;/a&gt; before, but the nay-sayers shut down the conversation before we had a good answer. The most valuable subscribers are the most likely to be sitting behind a proxy server and the most likely to be lost in the shuffle. Just how is RSS going to address that?
&lt;/p&gt;
&lt;p&gt;Maybe I&apos;m dense. But I don&apos;t see how anyone is going to build a RSS user database, segment the users and target the segments independently &amp;ndash; remembering that a user may belong to multiple segments. I happen to believe in 1-to-1 marketing, how does RSS fit into that world?
&lt;/p&gt;
&lt;p&gt;And &lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/2003/07/28.html#a424&quot; title=&quot;My RSS Brand&quot;&gt;don&apos;t expect to control presentation in my RSS aggregator&lt;/a&gt;. I don&apos;t think one-page aggregators are going away and I don&apos;t think anyone is up to the job of blending dozen&apos;s of presentation formats on the same page.
&lt;/p&gt;
&lt;p&gt;Now, maybe spam spells the end of email marketing. But I think email is important enough that we&apos;ll fix it before it dies. And that we&apos;ll see RSS become one of the tools in marketing&apos;s toolchest &amp;ndash; supplementing email, not replacing it.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/19.html#a489</guid>
			<pubDate>Tue, 19 Aug 2003 13:48:34 GMT</pubDate>
			<source url="http://rss.lockergnome.com/xml/all.xml">Lockergnome&apos;s RSS Resource</source>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=489&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F19.html%23a489</comments>
			</item>
		<item>
			<title>Hibernate Prototyping with the BeanShell</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/18.html#a487</link>
			<description>&lt;p&gt;Just playing around is one of my favorite ways of becoming familiar with software.
Let&apos;s see how we can use the &lt;a href=&quot;http://www.beanshell.org/&quot;&gt;BeanShell&lt;/a&gt;
to prototype Hibernate.
I&apos;m partial towards the BeanShell
because it&apos;s embedded in my
&lt;a href=&quot;http://jdee.sunsite.dk/&quot;&gt;Java Development Environment for Emacs&lt;/a&gt;.
But if you&apos;re so inclined,
then &lt;a href=&quot;http://www.jython.org/&quot;&gt;Jython&lt;/a&gt; will probably do as well.
Just in case there is a lurking configuration gotcha, here&apos;s
&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/java/hibernate/configuration.html&quot;&gt;my current Java software configuration&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;I must confess that I wasn&apos;t planning on using the BeanShell.
I was planning on adding a simple interpreter with
&lt;a href=&quot;http://java.sun.com/j2se/1.4.2/docs/api/java/io/StreamTokenizer.html&quot;&gt;java.io.StreamTokenizer&lt;/a&gt;
to allow interactive manipulation of Keyword and KeySet objects.
And then I realized that by setting the fork attribute of the java task to true
separated my application from the console input.
And setting it to false terminates the application with an java.lang.ExceptionInInitializerError.
The
&lt;a href=&quot;http://www.beanshell.org/&quot;&gt;BeanShell&lt;/a&gt;
was my ticket out.
&lt;/p&gt;
&lt;p&gt;BeanShell support requires just a handfull of minor changes to our build file.
First,
the BSH property is added to reference the BeanShell jar
and
it is prepended to classpath.run to form classpath.bsh.
Second,
a new bsh target is added in parallel to the run target
&amp;mdash;
note that we use class bsh.Console rather than bsh.Interpreter
because we still lose access to console input because of the JVM fork.
And Finally,
the dist target was modified to include a bsh sub-directory.
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
&amp;lt;project default=&quot;all&quot;&amp;gt;
         &amp;lt;!-- ... --&amp;gt;
  &amp;lt;property name=&quot;LOG4J&quot;    location=&quot;/Projects/Java/Lib/log4j.jar&quot; /&amp;gt;
  &lt;b&gt;&amp;lt;property name=&quot;BSH&quot;      location=&quot;/Projects/Java/Lib/bsh.jar&quot; /&amp;gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;         &amp;lt;!-- ... --&amp;gt;
  &lt;b&gt;&amp;lt;path id=&quot;classpath.bsh&quot;&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;pathelement location=&quot;${BSH}&quot; /&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;path refid=&quot;classpath.run&quot; /&amp;gt;&lt;/b&gt;
  &amp;lt;/path&amp;gt;&lt;br&gt;&lt;br&gt;         &amp;lt;!-- ... --&amp;gt;
  &amp;lt;target name=&quot;setup-run&quot; depends=&quot;clean-run&quot;&amp;gt;
    &amp;lt;condition property=&quot;LOG4J_OUT&quot; value=&quot;log4j-to-stdout.properties&quot;&amp;gt;
      &amp;lt;istrue value=&quot;${TALK}&quot;/&amp;gt;
    &amp;lt;/condition&amp;gt;
    &amp;lt;condition property=&quot;LOG4J_OUT&quot; value=&quot;log4j-to-file.properties&quot;&amp;gt;
      &amp;lt;isfalse value=&quot;${TALK}&quot;/&amp;gt;
    &amp;lt;/condition&amp;gt;
  &amp;lt;/target&amp;gt;
  &amp;lt;target name=&quot;run&quot; depends=&quot;compile,setup-run&quot;&amp;gt;
    &amp;lt;java classname=&quot;Main&quot;
          fork=&quot;true&quot;&amp;gt;
      &amp;lt;classpath refid=&quot;classpath.run&quot; /&amp;gt;
      &amp;lt;sysproperty key=&quot;log4j.configuration&quot; value=&quot;${LOG4J_OUT}&quot; /&amp;gt;
    &amp;lt;/java&amp;gt;
  &amp;lt;/target&amp;gt;
  &lt;b&gt;&amp;lt;target name=&quot;bsh&quot; depends=&quot;compile,setup-run&quot;&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;java classname=&quot;bsh.Console&quot;&lt;/b&gt;
          &lt;b&gt;fork=&quot;true&quot;&amp;gt;&lt;/b&gt;
      &lt;b&gt;&amp;lt;classpath refid=&quot;classpath.bsh&quot; /&amp;gt;&lt;/b&gt;
      &lt;b&gt;&amp;lt;sysproperty key=&quot;log4j.configuration&quot; value=&quot;${LOG4J_OUT}&quot; /&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;/java&amp;gt;&lt;/b&gt;
  &lt;b&gt;&amp;lt;/target&amp;gt;&lt;/b&gt;
  &amp;lt;target name=&quot;clean-run&quot;&amp;gt;
    &amp;lt;delete verbose=&quot;${TALK}&quot; file=&quot;hibernate.log&quot; /&amp;gt;
  &amp;lt;/target&amp;gt;&lt;br&gt;&lt;br&gt;         &amp;lt;!-- ... --&amp;gt;
  &amp;lt;target name=&quot;dist&quot;&amp;gt;
    &amp;lt;zip destfile=&quot;distrib.zip&quot;
         basedir=&quot;.&quot;
         includes=&quot;build.xml,src/**,cfg/**,&lt;b&gt;bsh/**&lt;/b&gt;&quot;
         excludes=&quot;src/prj.el&quot;
         /&amp;gt;
  &amp;lt;/target&amp;gt;
         &amp;lt;!-- ... --&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Next, we&apos;ll create a &lt;a href=&quot;http://www.beanshell.org/manual/quickstart.html#Scripted_Objects&quot;&gt;Scripted Object&lt;/a&gt; to simplify our interaction with hibernate.
The Hibernate method returns an object that provides easy access to
the most common functionality: open, save, find, delete and close.
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.MappingException;
import net.sf.hibernate.HibernateException;&lt;br&gt;&lt;br&gt;Hibernate() {
    Configuration cfg = new Configuration();
    cfg.addClass( hb.Keyword.class );
    cfg.addClass( hb.KeySet.class );
    SessionFactory factory = cfg.buildSessionFactory();
    Session session = factory.openSession();&lt;br&gt;&lt;br&gt;    void open() {
        session = factory.openSession();
    }&lt;br&gt;&lt;br&gt;    void close() {
        session = null;
    }&lt;br&gt;&lt;br&gt;    void save( Object o ) {
        session.saveOrUpdate( o );
    }&lt;br&gt;&lt;br&gt;    void delete( Object o ) {
        session.delete( o );
    }&lt;br&gt;&lt;br&gt;    Transaction transaction() {
        return session.beginTransaction();
    }&lt;br&gt;&lt;br&gt;    Object findByName( String className, String objName )
    {
        java.util.List existing;
        if ( objName == null || objName.length()==0 ) {
            existing = session.find( &quot;from &quot; + className );
        }
        else {
            existing = session.find( &quot;from &quot; + className +
                                     &quot; as o where o.name=&apos;&quot; + objName + &quot;&apos;&quot; );
        }&lt;br&gt;&lt;br&gt;        if ( existing.isEmpty() ) {
            return null;
        }
        else {
            return existing.get(0);
        }
    }&lt;br&gt;&lt;br&gt;    return this;
}
&lt;/pre&gt;
&lt;p&gt;Finally, two methods were added each of the KeySet and Keyword classes.
The KeySet class gained an add and a remove method that simply provide
access to the corresponding methods of the java.util.Set member variable.
And the Keyword class gained methods for hashCode and equals
&amp;mdash;
this insures that Keyword objects are equivalent
when their String member variables are equivalent.
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
public class Keyword {
    //...
    /**
     * Hashcode generation
     */
    public int hashCode()
    {
        return ( this.name == null ) ? 0 : this.name.hashCode();
    }&lt;br&gt;&lt;br&gt;    /**
     * Equality test
     * @param other The Object to be checked for equality
     */
    public boolean equals(Object other) {
        boolean equality = false;&lt;br&gt;&lt;br&gt;        if ( this.getClass() == other.getClass() ) {
            Keyword otherWord = (Keyword) other;&lt;br&gt;&lt;br&gt;            if ( this.id != unset_value &amp;&amp; this.id == otherWord.id ) {
                equality = true;
            }
            else if ( this.name.equals( otherWord.name) ) {
                equality = true;
                if ( this.id == unset_value ) {
                    this.id = otherWord.id;
                }
                else if ( otherWord.id == unset_value ) {
                    otherWord.id = this.id;
                }
            }
        }&lt;br&gt;&lt;br&gt;        return equality;
    }
    // ...
}
&lt;/pre&gt;
&lt;p&gt;
And now we&apos;re ready to play with the BeanShell (starting with an empty database).
By the way,
if you&apos;re anything like me,
then the number one thing to remember is use print rather than println.
&lt;/p&gt;
&lt;center&gt;&lt;img border=&quot;0&quot; alt=&quot;Picture of hibernate interaction in the BeanShell console&quot; src=&quot;http://radio.weblogs.com/0118153/categories/software/java/hibernate/bsh.gif&quot;&gt;&lt;/center&gt;
&lt;p&gt;We can use the BeanShell to see that we &lt;strike&gt;cannot use Hibernate
for immutable objects&lt;/strike&gt; need to be careful when comparing objects from different sessions:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
1.3b2 - by Pat Niemeyer (pat@pat.net)
bsh % source(&quot;bsh/Hibernate.bsh&quot;);
bsh % import hb.*;
bsh % hb = Hibernate();
bsh % x = hb.findByName(&quot;Keyword&quot;,&quot;this&quot;);
bsh % y = hb.findByName(&quot;Keyword&quot;,&quot;this&quot;);
bsh % hb.close();
bsh % hb.open();
bsh % z = hb.findByName(&quot;Keyword&quot;,&quot;this&quot;);
bsh % hb.close();
bsh % print( (x==y) ? &quot;equal&quot; : &quot;not-equal&quot; );
equal
bsh % print( (x==z) ? &quot;equal&quot; : &quot;not-equal&quot; );
not-equal
bsh % 
&lt;/pre&gt;
&lt;p&gt;We also see that Hibernate performs a shallow save rather than a deep save:&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
1.3b2 - by Pat Niemeyer (pat@pat.net)
bsh % source(&quot;bsh/Hibernate.bsh&quot;);
bsh % import hb.*;
bsh % hb = Hibernate();
bsh % tx = hb.transaction();
bsh % a = new Keyword(&quot;red&quot;);
bsh % s = new KeySet(&quot;colors&quot;);
bsh % s.add(a);
bsh % print(s);
{-1:colors|[-1:red]}
bsh % hb.save(s);
bsh % tx.commit();
// Error: // Uncaught Exception: Method Invocation tx.commit :
                                 at Line: 1 : in file: &amp;lt;unknown file&amp;gt;
                                 : tx .commit ( )&lt;br&gt;&lt;br&gt;Target exception: net.sf.hibernate.TransientObjectException:
                                 object references an unsaved transient instance
                                 - save the transient instance before flushing&lt;br&gt;&lt;br&gt;net.sf.hibernate.TransientObjectException:
                                 object references an unsaved transient instance
                                 - save the transient instance before flushing
	at net.sf.hibernate.impl.SessionImpl.getEntityIdentifierIfNotUnsaved
                                 (SessionImpl.java:2357)
	at net.sf.hibernate.type.EntityType.getIdentifier(EntityType.java:55)
	at net.sf.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:33)
	at net.sf.hibernate.collection.CollectionPersister.writeElement
                                 (CollectionPersister.java:458)
	at net.sf.hibernate.collection.Set.writeTo(Set.java:226)
	at net.sf.hibernate.collection.CollectionPersister.recreate
                                 (CollectionPersister.java:692)
	at net.sf.hibernate.impl.ScheduledCollectionRecreate.execute
                                 (ScheduledCollectionRecreate.java:23)
	at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2101)
	at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2077)
	at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2017)
	at net.sf.hibernate.transaction.JDBCTransaction.commit
                                 (JDBCTransaction.java:57)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke
                                 (NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke
                                 (DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:324)
	at bsh.Reflect.invokeOnMethod(Unknown Source)
	at bsh.Reflect.invokeObjectMethod(Unknown Source)
	at bsh.Name.invokeMethod(Unknown Source)
	at bsh.BSHMethodInvocation.eval(Unknown Source)
	at bsh.BSHPrimaryExpression.eval(Unknown Source)
	at bsh.BSHPrimaryExpression.eval(Unknown Source)
	at bsh.Interpreter.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:554)
bsh % tx.rollback();
bsh % hb.close();
&lt;/pre&gt;
&lt;p&gt;We&apos;re done for now.
You&apos;re ready to download the
&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/java/hibernate/bsh.zip&quot;&gt;source to prototype Hibernate with the BeanShell&lt;/a&gt; and play.
&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt;
I don&apos;t claim to be an expert on hibernate.
Please
&lt;a href=&quot;http://radio.xmlstoragesystem.com/rcsPublic/mailto?usernum=0118153&quot;&gt;send&lt;/a&gt;
comments and corrections.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/18.html#a487</guid>
			<pubDate>Mon, 18 Aug 2003 13:01:29 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=487</comments>
			</item>
		<item>
			<title>Drawing the Line</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/14.html#a483</link>
			<description>&lt;p&gt;One of the hardest tasks in developing new systems is knowing where to draw the line &amp;mdash; include too much and you&apos;ll never finish, include too little and all you have is a toy. So I think that Joi is being a bit harsh in his guess that &lt;a href=&quot;http://joi.ito.com/archives/2003/08/14/email_is_officially_broken.html&quot; Title=&quot;Email is officially broken&quot;&gt;there were people who were voicing concerns who had more vision&lt;/a&gt;. The problem lies in separating the true visionaries from the false prophets. SMTP and IPv4 have had a pretty good run over the past few decades &amp;mdash; not too bad for what were essentially 0.x releases.
&lt;/p&gt;
&lt;p&gt;Now if Joi wants to throw some brickbats at those who deny that there is a problem or those who stand in the way of improvement while waiting for a perfect solution, then the line forms behind me.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/14.html#a483</guid>
			<pubDate>Thu, 14 Aug 2003 15:33:21 GMT</pubDate>
			<source url="http://joi.ito.com/index.xml">Joi Ito&apos;s Web</source>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=483&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F14.html%23a483</comments>
			</item>
		<item>
			<title>Welcome to the Neighbloghood</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/13.html#a474</link>
			<description>&lt;p&gt;I was doing the usual obsessive compulsive review of my referrals when I came across &lt;a href=&quot;http://www.fredshouse.net/&quot;&gt;fredshouse.net&lt;/a&gt;. Gene and I go waaay back, and I&apos;m happy to welcome him to the blogroll (maybe this will get him off the snide at &lt;a href=&quot;http://www.technorati.com/cosmos/links.html?rank=&amp;url=http://www.fredshouse.net&amp;sub=Get+Link+Cosmos&quot;&gt;Technorati&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;In other blogroll news, the
&lt;a href=&quot;http://www.ballblog.com&quot;&gt;BallBlog&lt;/a&gt;
is joining the blog gang at
&lt;a href=&quot;http://www.fanblogs.com&quot;&gt;FanBlogs&lt;/a&gt;.
I think that we&apos;re going to see more blogging confederations
as individuals find themselves unable to write as frequently as they&apos;d like.
&lt;/p&gt;
&lt;p&gt;
Maybe it&apos;s a function of the tools,
but I&apos;m surprised that I don&apos;t see more
confederations formed by a
central blog linking to contributor blogs.
It&apos;s hard for an individual to maintain critical mass over multiple categories
&amp;mdash;
just take a look at my
&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/sports/2003/07/20.html&quot;&gt;Sports Category&lt;/a&gt; for July.
But a group can easily maintain an on-topic critical mass
while letting the individuals maintain a more eclectic style at home.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/13.html#a474</guid>
			<pubDate>Wed, 13 Aug 2003 12:51:08 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=474&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F13.html%23a474</comments>
			</item>
		<item>
			<title>Three Laws of Nonsense</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/11.html#a465</link>
			<description>&lt;p&gt;From &lt;a href=&quot;http://www.steptwo.com.au/columntwo/archives/000815.html&quot; title=&quot;Three laws of nonsense&quot;&gt;Column two&lt;/a&gt;, a reminder of why we need to understand stakeholder perspectives before reaching conclusions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The source of nonsense is that for every piece of nonsense there exists an irrelevant frame of reference in which the item is sensible.
&lt;li&gt;The persistance of nonsense comes from rigorous arguments from inapplicable assumptions.
&lt;li&gt;The diffusion of nonsense results from the fact that people are more specialist than problems.
&lt;/ol&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/11.html#a465</guid>
			<pubDate>Mon, 11 Aug 2003 13:50:38 GMT</pubDate>
			<source url="http://www.steptwo.com.au/columntwo/index.xml">Column Two</source>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=465&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F11.html%23a465</comments>
			</item>
		<item>
			<title>Full Posts vs Headlines</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/10.html#a461</link>
			<description>&lt;p&gt;Sean Bonner would like for everyone to &lt;a href=&quot;http://www.seanbonner.com/blog/archives/000468.php&quot; title=&quot;RSS Request&quot;&gt;change your RSS feed [to] display your WHOLE post&lt;/a&gt;. I think that Sean is talking to the wrong audience &amp;mdash; he should be appealing to the NewsReader developers.
&lt;/p&gt;
&lt;p&gt;I choose to make the full content of &lt;a href=&quot;http://radio.weblogs.com/0118153/&quot;&gt;Take the First Step&lt;/a&gt; is available in my RSS feeds. But if someone has made a conscious decision to have excerpts rather than the full post in their feed, then that&apos;s fine by me. In fact, if &lt;a href=&quot;http://radio.weblogs.com/0118153/2003/07/28.html#a424&quot; title=&quot;My RSS Brand&quot;&gt;their website is part of their brand&lt;/a&gt;, then that&apos;s the right choice for them.
&lt;/p&gt;
&lt;p&gt;What Sean really needs is a NewsReader that acknowledges that we live in a world of &lt;strong&gt;Always drifting between On and Off&lt;/strong&gt;. A reader that would let him mark articles to be downloaded and read at a later time. And eventually, a Reader with predictive capability that could pre-fetch articles for you.
&lt;/p&gt;
&lt;p&gt;via &lt;a href=&quot;http://rss.lockergnome.com/archives/help/006512.phtml&quot; title=&quot;Full Posts vs Headlines&quot;&gt;Lockergnome&apos;s RSS Resource&lt;/a&gt;.&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/10.html#a461</guid>
			<pubDate>Sun, 10 Aug 2003 13:27:02 GMT</pubDate>
			<source url="http://rss.lockergnome.com/xml/all.xml">Lockergnome&apos;s RSS Resource</source>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=461&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F10.html%23a461</comments>
			</item>
		<item>
			<title>A Persistent Collection with Hibernate</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/06.html#a450</link>
			<description>&lt;p&gt;Our series on Hibernate continues
with the addition of a Hibernate collection.
The collection is a basic building block in programming
and
storing Keyword objects inside a KeySet collection object
gives us an easy way to query and display our persistent objects.
&lt;/p&gt;
&lt;p&gt;The first step in implementing our KeySet class
is deciding whether there will be a one-to-many or a many-to-many
relationship between KeySet and Keyword objects.
A Keyword object may not be contained in multiple KeySet objects
in a one-to-many relationship
and
it may be contained in multiple KeySet objects
in a many-to-many relationship.
&lt;/p&gt;
&lt;p&gt;This example will use a many-to-many relationship.
This requires a new table
with two foreign keys tying KeySets and Keywords rows together
&amp;mdash;
a one-to-many relationship would require a foreign key in the
Keywords table that referenced the KeySets table.
The KeySet.hbm.xml file follows
(comments show the SQL used to create the respective tables).
It is quite similar to the Keyword.hbm.xml file
with the addition of the set tag.
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
&amp;lt;hibernate-mapping&amp;gt;
  &amp;lt;!-- CREATE TABLE KEYSETS ( ID IDENTITY, NAME VARCHAR(25) );
    --&amp;gt;
  &amp;lt;class name=&quot;hb.KeySet&quot; 
         table=&quot;keysets&quot;&amp;gt;&lt;br&gt;&lt;br&gt;    &amp;lt;id name=&quot;id&quot; 
        type=&quot;integer&quot;
        column=&quot;id&quot;
        unsaved-value=&quot;-1&quot;&amp;gt;
      &amp;lt;generator class=&quot;identity&quot;/&amp;gt;
    &amp;lt;/id&amp;gt;&lt;br&gt;&lt;br&gt;    &amp;lt;property name=&quot;name&quot; 
              column=&quot;NAME&quot; 
              not-null=&quot;true&quot; 
              unique=&quot;true&quot;
              /&amp;gt;&lt;br&gt;&lt;br&gt;    &amp;lt;!-- CREATE TABLE KEYSET_WORD ( SET_ID INTEGER NOT NULL,
                        KEY_ID INTEGER NOT NULL,
                        PRIMARY KEY ( SET_ID, KEY_ID ),
                        FOREIGN KEY ( SET_ID ) references KEYSETS(ID),
                        FOREIGN KEY ( KEY_ID ) references KEYWORDS(ID) );
      --&amp;gt;
    &amp;lt;set name=&quot;keys&quot;
         lazy=&quot;false&quot;
         table=&quot;keyset_word&quot;&amp;gt;
      &amp;lt;key column=&quot;set_id&quot;/&amp;gt;
      &amp;lt;many-to-many class=&quot;hb.Keyword&quot;
                    column=&quot;key_id&quot;
                    /&amp;gt;
    &amp;lt;/set&amp;gt;&lt;br&gt;&lt;br&gt;  &amp;lt;/class&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;We will skip the KeySet.java class
as it is primarily boilerplate get/set methods
and
is quite similar to the Keyword.java class.
However, please &lt;strong&gt;note&lt;/strong&gt; that
there are some changes to our Keyword implementation:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The parameter definition &lt;strong&gt;unsaved-value=&quot;-1&quot;&lt;/strong&gt;
has been added to Keyword.hbm.xml to explicitly declare
an unsaved id value.
And the &lt;strong&gt;static final int unsaved_value = -1&lt;/strong&gt;
has been added to the Keyword java file
and
is used to set the initial value of the id member value.
The two values need to match
and
should correspond to an invalid id value.&lt;/li&gt;
&lt;li&gt;The default constructor and the setId function are now protected.
Hibernate sets the id when an object is loaded or saved
and everything else should leave it alone.&lt;/li&gt;
&lt;li&gt;A toString() method has been added for easy output.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In addition,
the build.xml file has been modified to add a DEBUG property
that defines the value of the debug attribute of the javac task.
The DEBUG property is set to true
and
Java source is now compiled with debug information.
&lt;/p&gt;
&lt;p&gt;Now let&apos;s take a look at some code to load, query and create
persistent objects.
First,
don&apos;t forget to add the class to the configuration object.
The error message
&quot;net.sf.hibernate.QueryException: unexpected token: as [from KeySet as ks ...]&quot;
can be a bit perplexing until you&apos;ve encountered it a few times.
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
    Configuration cfg = new Configuration();
    cfg.addClass( hb.Keyword.class );
    cfg.addClass( hb.KeySet.class );&lt;br&gt;&lt;br&gt;    SessionFactory sessions = cfg.buildSessionFactory();
    Session session = sessions.openSession();
&lt;/pre&gt;
&lt;p&gt;Second,
let&apos;s query for a KeySet object.
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
        tx = session.beginTransaction();
        List existing = session.find( &quot;from KeySet as ks where ks.name=&apos;colors&apos;&quot; );
&lt;/pre&gt;
&lt;p&gt;If we find the KeySet we&apos;re looking for,
then we print it.
Otherwise,
we create a KeySet object,
populate it with two Keyword objects
and
persist all three objects.
&lt;pre class=&quot;code&quot;&gt;
        if ( ! existing.isEmpty() ) {
            ks = (KeySet) existing.get(0);
            System.out.println( &quot;Read &quot; + ks );
        }
        else {
            Set set = new HashSet();&lt;br&gt;&lt;br&gt;            kw = new Keyword( &quot;red&quot; );
            session.save( kw );
            set.add( kw );&lt;br&gt;&lt;br&gt;            kw = new Keyword( &quot;blue&quot; );
            session.save( kw );
            set.add( kw );&lt;br&gt;&lt;br&gt;            ks = new KeySet( &quot;colors&quot; );
            ks.setKeys( set );
            session.save( ks );&lt;br&gt;&lt;br&gt;            System.out.println( &quot;Create &quot; + ks );
        }
        tx.commit();
&lt;/pre&gt;
&lt;p&gt;Now,
start with a clean database
and
execute twice:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
$ ant run
Buildfile: build.xml&lt;br&gt;&lt;br&gt;init:&lt;br&gt;&lt;br&gt;compile:&lt;br&gt;&lt;br&gt;clean-run:&lt;br&gt;&lt;br&gt;setup-run:&lt;br&gt;&lt;br&gt;run:
     [java] Create {0:colors|[1:blue, 0:red]}&lt;br&gt;&lt;br&gt;BUILD SUCCESSFUL
Total time: 14 seconds
$ ant run
Buildfile: build.xml&lt;br&gt;&lt;br&gt;init:&lt;br&gt;&lt;br&gt;compile:&lt;br&gt;&lt;br&gt;clean-run:
   [delete] Deleting: /Projects/Learn/Hibernate/Simple/hibernate.log&lt;br&gt;&lt;br&gt;setup-run:&lt;br&gt;&lt;br&gt;run:
     [java] Read {0:colors|[0:red, 1:blue]}&lt;br&gt;&lt;br&gt;BUILD SUCCESSFUL
Total time: 13 seconds
&lt;/pre&gt;
&lt;p&gt;Success,
we&apos;ve stopped adding persistent objects to the database
with every execution.
And we&apos;ve stored and retrieved objects.
You can download the
&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/java/hibernate/collection.zip&quot;&gt;source
for this simple Hibernate collection&lt;/a&gt;.
As a reminder,
here is my
&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/java/hibernate/configuration.html&quot;&gt;hibernate software configuration&lt;/a&gt;.
&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt;
I don&apos;t claim to be an expert on hibernate.
Please
&lt;a href=&quot;http://radio.xmlstoragesystem.com/rcsPublic/mailto?usernum=0118153&quot;&gt;send&lt;/a&gt;
comments and corrections.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/06.html#a450</guid>
			<pubDate>Wed, 06 Aug 2003 13:10:55 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=450</comments>
			</item>
		<item>
			<title>I&apos;ve Grown Accustomed to Radio Userland</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/05.html#a447</link>
			<description>&lt;p&gt;&lt;a href=&quot;http://www.typepad.com&quot;&gt;TypePad&lt;/a&gt; goes live
and it will soon be time to fish or cut bait.
Will it be TypePad,
&lt;a href=&quot;http://radio.userland.com&quot;&gt;Radio Userland&lt;/a&gt;,
or both?
I&apos;ve been part of the TypePad beta over the past month,
and
it has been a very pleasant experience.
I would not hesitate to recommend TypePad.
&lt;/p&gt;
&lt;p&gt;TypePad has some features that Radio lacks.
It was nice to be able to create an extended post
rather than my standard hack of an excerpt on
my home weblog pointing to a full post
in the software category.
And since I tend to ruminate over my postings for a bit,
I liked how TypePad let me control the time associated with my post.
And while I didn&apos;t have any problems with TypePad,
I did have some questions
and it was good to have an infrastructure for help tickets.
&lt;/p&gt;
&lt;p&gt;But I&apos;ve grown accustomed to Radio Userland.
I like having a local system.
The Radio news reader is still my favorite.
And it&apos;s a real pain to move a weblog.
So right now,
I&apos;m leaning towards staying put.
I think the next move for Take the First Step will be
when I get my own domain name.
Now if I could only snag a good name.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/05.html#a447</guid>
			<pubDate>Tue, 05 Aug 2003 12:40:20 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=447&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F05.html%23a447</comments>
			</item>
		<item>
			<title>This is True</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/02.html#a441</link>
			<description>&lt;p&gt;I&apos;ve been predicting the conversion of newsletters
&lt;a href=&quot;http://radio.weblogs.com/0118153/2003/05/12.html&quot;
title=&quot;Spam, Newsletters and RSS&quot;&gt;from email to RSS&lt;/a&gt;
for a while now,
so it feels good to be proven correct.
The free version of &lt;a href=&quot;http://www.thisistrue.com/rss.html&quot; title=&quot;This is True: What is RSS?&quot;&gt;This is True&lt;/a&gt;
is now available via RSS:
&lt;/p&gt;
&lt;blockquote&gt;By using a special reader, you can get regular information -- including news and newsletter subscriptions -- from multiple web sites, all in one place. No more running from site to site to see if there are updates you are interested in. This is True&apos;s free edition is now available by RSS feed.
&lt;br&gt;...&lt;br&gt;
&lt;p&gt;There&apos;s much more info coming, but for now here are some places to get you
started (as always, outside links open in a new window):&lt;/p&gt;
&lt;UL&gt;&lt;LI&gt;If you use MS Outlook (&lt;I&gt;not&lt;/i&gt; Outlook Express) an excellent integrated reader is
&lt;A HREF=&quot;http://www.NewsGator.com&quot; TARGET=&quot;new&quot;&gt;News Gator&lt;/a&gt;&lt;/LI&gt;
&lt;LI&gt;A web-based aggregator:
&lt;A HREF=&quot;http://www.oreillynet.com/meerkat/&quot; TARGET=&quot;new&quot;&gt;Meercat&lt;/a&gt;&lt;/LI&gt;
&lt;LI&gt;A stand-alone program for Windows: &lt;A HREF=&quot;http://www.headlineviewer.com&quot; TARGET=&quot;new&quot;&gt;Headline Viewer&lt;/a&gt;.
Others include &lt;A HREF=&quot;http://www.newzcrawler.com&quot; TARGET=&quot;new&quot;&gt;NewzCrawler&lt;/a&gt;,
&lt;A HREF=&quot;http://www.serence.com/site.php?action=ser_products,prod_klipfolio&quot; TARGET=&quot;new&quot;&gt;KlipFolio&lt;/a&gt;,
and &lt;A HREF=&quot;http://www.bradsoft.com/feeddemon/index.asp&quot; TARGET=&quot;new&quot;&gt;FeedDemon&lt;/a&gt;
(still in beta)&lt;/LI&gt;
&lt;LI&gt;A stand-alone progrom for Macintosh (OS-X): &lt;A HREF=&quot;http://ranchero.com/netnewswire/&quot; TARGET=&quot;new&quot;&gt;NetNewsWire&lt;/a&gt;&lt;/LI&gt;
&lt;LI&gt;For an interesting tutorial (mainly targeting publishers), see
&lt;A HREF=&quot;http://www.mnot.net/rss/tutorial/&quot; TARGET=&quot;new&quot;&gt;this page&lt;/a&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;/blockquote&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/02.html#a441</guid>
			<pubDate>Sat, 02 Aug 2003 14:09:15 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=441&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F02.html%23a441</comments>
			</item>
		<item>
			<title>Fear of Failure</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/08/01.html#a437</link>
			<description>&lt;p&gt;We&apos;ve all heard the sports bromide &lt;em&gt;play to win&lt;/em&gt;.
So it&apos;s quite interesting that
&lt;a href=&quot;http://www.nytimes.com/2003/07/30/sports/30risk.html?ex=1374897600&amp;en=7706d24235f0c2d6&amp;ei=5007&amp;partner=USERLAND&quot;&gt;scientists say that managers, coaches and players are too cautious&lt;/a&gt;
for their own good.
It seems that their focus on the worst-case scenario
prevents them from following the optimum strategy
&amp;ndash;
fear of failure trumps cold logic.
&lt;/p&gt;
&lt;p&gt;Contrast that with Silicon Valley
&amp;mdash;
the characteristic that is hardest to duplicate is it&apos;s acceptance of failure.
A stint at a failed company is a black mark in most places.
In Silicon Valley,
it&apos;s a degree from the school of hard knocks.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/08/01.html#a437</guid>
			<pubDate>Fri, 01 Aug 2003 22:14:49 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=437&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F08%2F01.html%23a437</comments>
			</item>
		<item>
			<title>My RSS Brand</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/07/28.html#a424</link>
			<description>&lt;p&gt;My RSS feeds contain the full text of
&lt;a href=&quot;http://radio.weblogs.com/0118153/&quot;&gt;Take the First Step&lt;/a&gt;.
I occasionally provide an excerpt on the main feed,
but I always provide the full text in the appropriate category
(&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/&quot;&gt;Software&lt;/a&gt;
and
&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/sports/&quot;&gt;Sports&lt;/a&gt;).
This is the right thing for me
&amp;mdash;
the content is my brand.
&lt;/p&gt;
&lt;p&gt;Presentation is part of the brand for many of us,
and
Zeldman carries the flag for those who
&lt;a href=&quot;http://www.zeldman.com/daily/0403a.shtml#unsyndicate&quot;&gt;like to see our writing in its visual context&lt;/a&gt;.
He
&lt;a href=&quot;http://www.zeldman.com/daily/0403a.shtml#fed&quot;&gt;hand rolls his feed&lt;/a&gt; to support his brand.
But don&apos;t try to extend your presentational brand into my news reader
and
expect me to be happy about it.
&lt;/p&gt;
&lt;p&gt;First of all,
I like my text black on white
and
I find a lot of weblogs hard to read because of their color choices.
I could put together a local style sheet.
But I like to think that people have a good reason for their style sheet choices.
And I prefer to respect those choices
(but if I could apply style sheets on a site by site basis,
then all bets are off).
&lt;/p&gt;
&lt;p&gt;And Second,
my news reader is currently presents up to 100 RSS items
on a single page.
Even if it were possible to present each item with a unique style,
I wouldn&apos;t want to look at it.
And aside from that,
are you really willing to test your style selections on
all the popular rendering engines?
&lt;/p&gt;
&lt;p&gt;If your web site is part of your brand,
then use your RSS feed to drive traffic back to it.
But don&apos;t expect to project your web site presentation back into my news reader.
Because it&apos;s probably not going to work.
And if it does work,
then I&apos;m probably going to unsubscribe.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/07/28.html#a424</guid>
			<pubDate>Mon, 28 Jul 2003 23:39:09 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=424&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F07%2F28.html%23a424</comments>
			</item>
		<item>
			<title>Musing about RSS</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/07/25.html#a418</link>
			<description>&lt;p&gt;The new
&lt;a href=&quot;http://weblog.infoworld.com/dickerson/2003/07/23.html#a85&quot;&gt;RSS feeds
from InfoWorld&lt;/a&gt;
are looking good.
They now provide a much better summary of the article
by including the first paragraph of the article.
Now, some would argue that the
&lt;a href=&quot;http://www.theshiftedlibrarian.com/2003/06/12.html#a4114&quot;&gt;feed
should provide the full article text&lt;/a&gt; in exchange for any ads,
but I think that underestimates the excerpt value.
Because they tell me to ignore InfoWorld
much more often then they tell me to pay attention.
And I&apos;m willing to trade an ad in my feed for that.
Hmmm, &lt;strong&gt;no ads today&lt;/strong&gt;
&amp;mdash;
did InfoWorld drop the RSS ad idea while I wasn&apos;t paying attention?
&lt;/p&gt;
&lt;p&gt;Plus, I think that it&apos;s only a matter of time before someone
adds predictive capability to a newsreader to pre-fetch
articles that you&apos;re likely to select.
Then we could head off on a plane or train with a stack of bits to read.
And why not mark an article to fetch
once a network connection is available?
On the way in, you could mark articles to read on the way back.
For all the promise of &lt;strong&gt;Always On&lt;/strong&gt;,
the reality is
&lt;strong&gt;Always drifting between On and Off&lt;/strong&gt;
&amp;mdash;
RSS newsreaders should reflect that reality.
&lt;/p&gt;
&lt;p&gt;And why don&apos;t more newsreaders download in the background?
I&apos;d much rather continue consuming my feed rather than waiting
for an article to load
&amp;mdash;
one of the big pluses of a web-based newsreader like
&lt;a href=&quot;http://radio.userland.com/&quot;&gt;Radio Userland&lt;/a&gt;
in a tab-cabable browser.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/07/25.html#a418</guid>
			<pubDate>Fri, 25 Jul 2003 13:49:05 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=418&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F07%2F25.html%23a418</comments>
			</item>
		<item>
			<title>Corporate/Personal Identity</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/07/24.html#a410</link>
			<description>&lt;p&gt;Maybe I&apos;m missing something,
but it seems to me that
&lt;a href=&quot;http://jrobb.mindplex.org/2003/07/20.html#a3342&quot;&gt;John Robb&apos;s
missing weblog&lt;/a&gt;
is not really about control.
It&apos;s really about the blurring of the lines between our
Corporate and our Personal Identities.
We don&apos;t expect to keep our email addresses
when we leave a company,
why would we expect to keep a corporate supplied weblog?
&lt;/p&gt;
&lt;p&gt;
If &lt;a href=&quot;http://www.userland.com/&quot;&gt;UserLand&lt;/a&gt; were to be
acquired by another company,
then
it&apos;s conceivable that we might someday see
&lt;a href=&quot;http://www.scripting.com/&quot;&gt;Scripting News&lt;/a&gt;
sundered from Dave Winer.
I&apos;m sure that Dave would try to negotiate ownership of Scripting News
as part of any acquistion.
But I have to think that Scripting News also represents
a significant corporate asset
and
it might not be on the table.
&lt;/p&gt;
&lt;p&gt;So the moral is to keep cognizant of corporate identity and assets
vs personal identity and assets.
Because they&apos;re not hard to keep separate if you start out that way.
But once they mingle,
corporate will win almost every time.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/07/24.html#a410</guid>
			<pubDate>Fri, 25 Jul 2003 03:11:15 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=410&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F07%2F24.html%23a410</comments>
			</item>
		<item>
			<title>An Envelope, not a Format</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/07/23.html#a404</link>
			<description>&lt;p&gt;RSS 2.0 has been rejuvenated
&amp;mdash;
both the
&lt;a href=&quot;http://scriptingnews.userland.com/2003/07/21#threeQuestionsAboutRss&quot;&gt;Triumvirate&lt;/a&gt;
and the
&lt;a href=&quot;http://www.cadenhead.org/workbench/2003/07/21.html#a806&quot;&gt;SSF-DEV&lt;/a&gt; are hard at work.
And as I&apos;ve been thinking about RSS,
I think that we need to emphasize RSS as an envelope, not a format.
&lt;/p&gt;
&lt;p&gt;Because the value of the envelope lies in the package that it delivers.
It liberates us from delivery concerns and
focuses our thoughts on the package.
And it forces us to recognize that the envelope can have different
meanings for different packages.
&lt;/p&gt;
&lt;p&gt;We need to leave some wiggle room for packages to interpret
the standard flexibly.
And while it would be nice to nail down the guid,
we don&apos;t really want to shackle all possible packages
with our existing weblog/aggregator implemenation baggage.
&lt;/p&gt;
&lt;p&gt;So please distinguish between what the standard wants,
and
how application domains interpret.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/07/23.html#a404</guid>
			<pubDate>Wed, 23 Jul 2003 13:13:15 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=404&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F07%2F23.html%23a404</comments>
			</item>
		<item>
			<title>I Love RSS</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/07/22.html#a399</link>
			<description>&lt;p&gt;&lt;a href=&quot;http://blogs.law.harvard.edu/tech/2003/07/20#a96&quot;&gt;&lt;img src=&quot;/0118153/images/iLoveRSS.gif&quot; border=&quot;0&quot; alt=&quot;I Love RSS&quot; align=&quot;right&quot; /&gt;&lt;/a&gt;Right now,
I&apos;m trying out the RSS capability inside
&lt;a href=&quot;http://www.oddpost.com/&quot;&gt;OddPost&lt;/a&gt;.
If I subscribe,
then OddPost would become the third aggregator that I&apos;ve purchased
(joining &lt;a href=&quot;http://radio.userland.com&quot;&gt;Radio UserLand&lt;/a&gt;
and
&lt;a href=&quot;http://www.newsgator.com&quot;&gt;NewsGator&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;The appeal of OddPost is that it makes RSS available via an IMAP server,
providing a single point to read and archive RSS.
I&apos;m also lobbying &lt;a href=&quot;http://www.fastmail.fm&quot;&gt;FastMail&lt;/a&gt;
(my IMAP email provider) to provide an equivalent capability
and looking at scripting Outlook and NewsGator.
And since I&apos;m already at &quot;Good Enough&quot;,
do nothing is always a leading contender.
We&apos;ll see what happens.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/07/22.html#a399</guid>
			<pubDate>Tue, 22 Jul 2003 12:32:32 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=399&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F07%2F22.html%23a399</comments>
			</item>
		<item>
			<title>Bravo</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/07/19.html#a394</link>
			<description>&lt;p&gt;&lt;a href=&quot;http://scriptingnews.userland.com/2003/07/18#rss20News&quot;&gt;RSS 2.0 spec to Berkman Center for Internet &amp; Society&lt;/a&gt; at Harvard Law School.
This is a big step forward.
&lt;a href=&quot;http://intertwingly.net/wiki/pie/RoadMap&quot;&gt;Pie/Necho/Atom&lt;/a&gt;
seems to be taking a revolutionary path rather than an evolutionary one.
And RSS 2.0 seemed to be painted in a corner.
But the transfer of copyright from
&lt;a href=&quot;http://www.userland.com/&quot;&gt;UserLand Software&lt;/a&gt;
to the
&lt;a href=&quot;http://cyber.law.harvard.edu/home/&quot;&gt;Berkman Center&lt;/a&gt;
opens up an evolutionary path for RSS 2.x.
&lt;/p&gt;
&lt;p&gt;Of course,
now the hard work begins
&amp;mdash;
where does RSS 2.0 go from here?
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/07/19.html#a394</guid>
			<pubDate>Sat, 19 Jul 2003 22:00:20 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=394&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0118153%2F2003%2F07%2F19.html%23a394</comments>
			</item>
		<item>
			<title>Controlling Hibernate Output with Log4J</title>
			<link>http://radio.weblogs.com/0118153/categories/software/2003/07/17.html#a386</link>
			<description>&lt;p&gt;Our
&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/2003/07/09.html#a365&quot;&gt;Simple Hibernate Application&lt;/a&gt;
is a bit verbose.
That&apos;s probably okay for a web application
because stdout actually ends up in a server log.
But it&apos;s a bit annoying in console application.
Fortunately,
Hibernate uses the
&lt;a href=&quot;http://jakarta.apache.org/commons/logging.html&quot;&gt;Apache commons-logging&lt;/a&gt;
abstraction layer
and
&lt;a href=&quot;http://hibernate.bluemars.net/14.html#62&quot;&gt;Hibernate logging is easily configured&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;First,
a quick aside on logging.
Logging packages are a mechanism that allow a developer
to add diagnostic messages to the code and
specify the message level and destination at runtime.
The design allows the developer to define a hierarchical logging structure
in which each level inherits the properties of the level above it
unless otherwise specified.
Typically,
the logging structure mirrors the package structure
as that is both simple and effective.
The &lt;a href=&quot;http://jakarta.apache.org/commons/logging/userguide.html&quot;&gt;JCL
Users Guide&lt;/a&gt; is a good place to start for more information.
&lt;/p&gt;
&lt;p&gt;Apache commons-logging supports the
&lt;a href=&quot;http://jakarta.apache.org/log4j/docs/index.html&quot;&gt;log4j&lt;/a&gt;,
JDK 1.4,
and
&lt;a href=&quot;http://jakarta.apache.org/commons/logging/api/org/apache/commons/logging/impl/SimpleLog.html&quot;&gt;JCL SimpleLog&lt;/a&gt;
Logging packages.
We&apos;ll use log4j because
I&apos;m already familiar with it
and
the Hibernate distribution includes a sample log4j.properties file.
&lt;/p&gt;
&lt;p&gt;Here are the required changes to our build.xml file (shown in bold).
First, there is a new property that locates the log4j jar file.
And second,
the log4j jar file is added to the execution classpath.
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
&amp;lt;project default=&quot;all&quot;&amp;gt;
  &amp;lt;property name=&quot;HBM-HOME&quot; location=&quot;/Projects/Java/hibernate&quot; /&amp;gt;
  &amp;lt;property name=&quot;JDBC&quot;     location=&quot;/Projects/Server/hsqldb/lib/hsqldb.jar&quot; /&amp;gt;
  &lt;b&gt;&amp;lt;property name=&quot;LOG4J&quot;    location=&quot;/Projects/Java/Lib/log4j.jar&quot; /&amp;gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;  &amp;lt;property name=&quot;src-dir&quot;  location=&quot;src&quot; /&amp;gt;
  &amp;lt;property name=&quot;cfg-dir&quot;  location=&quot;cfg&quot; /&amp;gt;
  &amp;lt;property name=&quot;obj-dir&quot;  location=&quot;obj&quot; /&amp;gt;
  &amp;lt;property name=&quot;TALK&quot;     value=&quot;false&quot; /&amp;gt;&lt;br&gt;&lt;br&gt;  &amp;lt;path id=&quot;classpath.base&quot;&amp;gt;
    &amp;lt;pathelement location=&quot;${obj-dir}&quot; /&amp;gt;
    &amp;lt;pathelement location=&quot;${HBM-HOME}/hibernate2.jar&quot; /&amp;gt;
    &amp;lt;fileset dir=&quot;${HBM-HOME}/lib&quot; includes=&quot;**/*.jar&quot; /&amp;gt;
    &amp;lt;pathelement location=&quot;${JDBC}&quot; /&amp;gt;
  &amp;lt;/path&amp;gt;
  &amp;lt;path id=&quot;classpath.run&quot;&amp;gt;
    &amp;lt;pathelement location=&quot;${cfg-dir}&quot; /&amp;gt;
    &amp;lt;path refid=&quot;classpath.base&quot; /&amp;gt;
    &lt;b&gt;&amp;lt;pathelement location=&quot;${LOG4J}&quot; /&amp;gt;&lt;/b&gt;
  &amp;lt;/path&amp;gt;&lt;br&gt;&lt;br&gt;  &amp;lt;target name=&quot;init&quot;&amp;gt;
    &amp;lt;mkdir dir=&quot;${obj-dir}&quot; /&amp;gt;
  &amp;lt;/target&amp;gt;&lt;br&gt;&lt;br&gt;  &lt;b&gt;...&lt;/b&gt;&lt;br&gt;&lt;br&gt;&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;p&gt;And here is the log4j.properties file from my hibernate distribution.
&lt;ul&gt;
&lt;li&gt;The first block of parameters define an output channel identified as stdout.
This channel directs messages to the standard output.&lt;/li&gt;
&lt;li&gt;The second block of parameters define an output channel identified as file.
This channel directs messages to the hibernate.log file.&lt;/li&gt;
&lt;li&gt;The rootLogger assignment defines the default behavior as
directing messages at or more severe than the warn level to the stdout channel.&lt;/li&gt;
&lt;li&gt;And the remaining assignments change the output levels to info
for the respective packages.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;code&quot;&gt;
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n&lt;br&gt;&lt;br&gt;### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n&lt;br&gt;&lt;br&gt;### set log levels - for more verbose logging change &apos;info&apos; to &apos;debug&apos; ##&lt;br&gt;&lt;br&gt;log4j.rootLogger=warn, stdout&lt;br&gt;&lt;br&gt;log4j.logger.net.sf.hibernate=info&lt;br&gt;&lt;br&gt;### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.net.sf.hibernate.connection.DriverManagerConnectionProvider=trace&lt;br&gt;&lt;br&gt;### log JDBC bind parameters ###
log4j.logger.net.sf.hibernate.type=info&lt;br&gt;&lt;br&gt;### log prepared statement cache activity ###
log4j.logger.net.sf.hibernate.ps.PreparedStatementCache=info
&lt;/pre&gt;
&lt;p&gt;The easiest solution is to simply uncomment the lines
defining the file channel
and
redefine the rootLogger to use the file channel.
This will direct the log output to the hibernate.log file.
&lt;pre class=&quot;code&quot;&gt;
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n&lt;br&gt;&lt;br&gt;### direct messages to file hibernate.log ###
&lt;b&gt;log4j.appender.file=org.apache.log4j.FileAppender&lt;/b&gt;
&lt;b&gt;log4j.appender.file.File=hibernate.log&lt;/b&gt;
&lt;b&gt;log4j.appender.file.layout=org.apache.log4j.PatternLayout&lt;/b&gt;
&lt;b&gt;log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n&lt;/b&gt;&lt;br&gt;&lt;br&gt;### set log levels - for more verbose logging change &apos;info&apos; to &apos;debug&apos; ##&lt;br&gt;&lt;br&gt;log4j.rootLogger=warn, &lt;b&gt;file&lt;/b&gt;&lt;br&gt;&lt;br&gt;log4j.logger.net.sf.hibernate=info&lt;br&gt;&lt;br&gt;### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.net.sf.hibernate.connection.DriverManagerConnectionProvider=trace&lt;br&gt;&lt;br&gt;### log JDBC bind parameters ###
log4j.logger.net.sf.hibernate.type=info&lt;br&gt;&lt;br&gt;### log prepared statement cache activity ###
log4j.logger.net.sf.hibernate.ps.PreparedStatementCache=info
&lt;/pre&gt;
&lt;p&gt;But here&apos;s another option.
We&apos;ll create two properties files,
one that directs the output to hibernate.log
and
another that directs the output to both System.out and hibernate.log.
Then we&apos;ll use the condition task and the java sysproperty task
to specify the desired configuration file based upon
the value of the TALK property.
&lt;pre class=&quot;code&quot;&gt;
&amp;lt;project default=&quot;all&quot;&amp;gt;
  &amp;lt; ... &amp;gt;&lt;br&gt;&lt;br&gt;  &lt;b&gt;&amp;lt;target name=&quot;setup-run&quot; depends=&quot;clean-run&quot;&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;condition property=&quot;LOG4J_OUT&quot; value=&quot;log4j-to-stdout.properties&quot;&amp;gt;&lt;/b&gt;
      &lt;b&gt;&amp;lt;istrue value=&quot;${TALK}&quot;/&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;/condition&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;condition property=&quot;LOG4J_OUT&quot; value=&quot;log4j-to-file.properties&quot;&amp;gt;&lt;/b&gt;
      &lt;b&gt;&amp;lt;isfalse value=&quot;${TALK}&quot;/&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;/condition&amp;gt;&lt;/b&gt;
  &lt;b&gt;&amp;lt;/target&amp;gt;&lt;/b&gt;
  &amp;lt;target name=&quot;run&quot; depends=&quot;compile&lt;b&gt;,setup-run&lt;/b&gt;&quot;&amp;gt;
    &amp;lt;java classname=&quot;Main&quot;
          fork=&quot;true&quot;&amp;gt;
      &amp;lt;classpath refid=&quot;classpath.run&quot; /&amp;gt;
      &lt;b&gt;&amp;lt;sysproperty key=&quot;log4j.configuration&quot; value=&quot;${LOG4J_OUT}&quot; /&amp;gt;&lt;/b&gt;
    &amp;lt;/java&amp;gt;
  &amp;lt;/target&amp;gt;
  &lt;b&gt;&amp;lt;target name=&quot;clean-run&quot;&amp;gt;&lt;/b&gt;
    &lt;b&gt;&amp;lt;delete verbose=&quot;${TALK}&quot; file=&quot;hibernate.log&quot; /&amp;gt;&lt;/b&gt;
  &lt;b&gt;&amp;lt;/target&amp;gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;  &amp;lt; ... &amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
Now we can specify via the command line whether to view
the logging messages on System.out or not.
&lt;pre class=&quot;code&quot;&gt;
$ ant run
Buildfile: build.xml&lt;br&gt;&lt;br&gt;init:&lt;br&gt;&lt;br&gt;compile:&lt;br&gt;&lt;br&gt;clean-run:&lt;br&gt;&lt;br&gt;setup-run:&lt;br&gt;&lt;br&gt;run:&lt;br&gt;&lt;br&gt;BUILD SUCCESSFUL
Total time: 12 seconds
$ wc -l hibernate.log 
      15 hibernate.log
$ ant -DTALK=true run
Buildfile: build.xml&lt;br&gt;&lt;br&gt;init:&lt;br&gt;&lt;br&gt;compile:&lt;br&gt;&lt;br&gt;clean-run:
   [delete] Deleting: /Projects/Learn/Hibernate/Simple/hibernate.log&lt;br&gt;&lt;br&gt;setup-run:&lt;br&gt;&lt;br&gt;run:
     [java] 15:38:16,872  INFO Environment:401
                          - Hibernate 2.0.1
     [java] 15:38:16,898  INFO Environment:435
                          - loaded properties ... 
     [java] 15:38:16,942  INFO Environment:450
                          - using CGLIB reflection optimizer
     [java] 15:38:17,029  INFO Environment:460
                          - JVM proxy support: true
     [java] 15:38:17,080  INFO Configuration:283 
                         - Mapping resource: hb/Keyword.hbm.xml
     [java] 15:38:20,273  INFO Binder:176
                          - Mapping class: hb.Keyword -&gt; keywords
     [java] 15:38:21,977  INFO SessionFactoryImpl:140
                               - building session factory
     [java] 15:38:22,114  INFO Dialect:37
                               - Using dialect: net.sf.hibernate.dialect.HSQLDialect
     [java] 15:38:22,167  INFO DriverManagerConnectionProvider:41
                               - Hibernate connection pool size: 2
     [java] 15:38:22,249  INFO DriverManagerConnectionProvider:70
                               - using driver: org.hsqldb.jdbcDriver
                                 at URL: jdbc:hsqldb:hsql://localhost
     [java] 15:38:22,259  INFO DriverManagerConnectionProvider:71
                               - connection properties: {user=user, password=user}
     [java] 15:38:22,260  INFO SessionFactoryImpl:170
                               - Use outer join fetching: false
     [java] 15:38:22,533  INFO SessionFactoryImpl:193
                               - Use scrollable result sets: true
     [java] 15:38:23,623  INFO SessionFactoryObjectFactory:82
                               - no JDNI name configured
     [java] 15:38:23,627  INFO SessionFactoryImpl:287
                               - Query language substitutions: {}&lt;br&gt;&lt;br&gt;BUILD SUCCESSFUL
Total time: 13 seconds
$ wc -l hibernate.log 
      15 hibernate.log
$ exit
&lt;/pre&gt;
&lt;p&gt;Our application still persists keyword objects without regard
for existing keyword objects,
but at least it does so quietly.
If you&apos;re following along,
then here is the source for our
&lt;a href=&quot;http://radio.weblogs.com/0118153/categories/software/java/hibernate/log4j.zip&quot;&gt;Simple Hibernate application with log4j&lt;/a&gt;.
We&apos;ll fix the persistence problem next.
&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt;
I don&apos;t claim to be an expert on hibernate.
Please
&lt;a href=&quot;http://radio.xmlstoragesystem.com/rcsPublic/mailto?usernum=0118153&quot;&gt;send&lt;/a&gt;
comments and corrections.
&lt;/p&gt;</description>
			<guid>http://radio.weblogs.com/0118153/categories/software/2003/07/17.html#a386</guid>
			<pubDate>Thu, 17 Jul 2003 13:08:27 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=118153&amp;amp;p=386</comments>
			</item>
		</channel>
	</rss>
