September 22nd, 2011 | Tags:

Whats does your internal collaboration enterprise social graph look like?

Let’s cut to the chase, this is how it should NOT look like:

Internal Collaboration Enterprise Social Graph of US Senate in 2009 by Slate (Credit: Slate.com)

Fig 1: Internal Collaboration Enterprise Social Graph of the US Senate – 2009  (Source: Slate.com)

The graph you are seeing above is a visual representation of internal collaboration enterprise social graph of the US Senate [This force directed graph from Slate is based on votes in 2009 (I will be working on a 2011 graph). Each blue dot represents a Democratic senator, each red dot represents a Republican senator. A line connects two senators when they voted the same way on 65 percent of the votes]. The force directed graph clusters dots with the most connections to each other, pushing away dots with the least connections and as a result we can visually identify the people who collaborate with each the most and those who collaborate the least.

In my engagements with various companies, I have observed that many people draw an enterprise social graph as dots connected by lines, some even go as far as drawing pretty clusters of dots connected by lines as shown in the US Senate graph above. While such a graph is not incorrect, it is not what you want your internal collaboration enterprise social graph to look like if you are to have effective internal collaboration. An effective internal collaboration enterprise social graph looks like this:

Internal Collaboration Enterprise Social Graph

Fig 2: Effective Internal Collaboration Enterprise Social Graph (Source: Tom Chikoore -http://tomchikoore.com)

It’s not pretty, it’s messy but it’s effective. Each dot represents an employee and each line represents two employees who follow each other on an internal social enterprise collaboration community. This means each line represents a “bi-directional” follow between two employees. A bidirectional follow represents an open communication channel for effective collaboration. The color of each dot represents department in the organization. The following is a legend for some of the organizational departments shown in the graph:

BLUE – Sales
RED – Engineering
SALMON – Product Marketing
FLUORESCNET GREEEN – Product Management
ORANGE – Marketing
BLACK – Professional Services
ACQUA – Support
QUALITY ASSURANCE – Saddle Brown
LIME GREEN – Vendor

From this graph, you can see that the departments that one would expect to collaborate with each other are collaborating with each other. This is a beautiful visualization: Notice how the Support team is positioned between Engineering and Professional Services; and Professional Service is positioned between Support and Sales. This is the type of relationship you would expect to see is the majority of product development organizations. QA is positioned right next to Engineering and Product Management is nestled between Engineering Product Marketing, and Sales. This is what you would expect in most organizations, this is what your internal collaboration enterprise social graph should look like.

You can think of graph depicted above as a depiction of the “internal collaboration DNA” of your organization. Using this graph and the right algorithms, an assessment of the health of your community is possible. The right tools can help you identify collaboration problems and suggest solutions to fix the problems to enable effective internal collaboration.

For more information on the social graph and community health assessment tools send me an email at tom AT tomchikoore.com

August 26th, 2011 | Tags:

After writing the “It’s a “Service” stupid” article, I have been asked to talk about SaaS to engineering teams at companies that are making the transition to a SaaS delivery model. I have posted my intro presentation on Slideshare:

RE: Trending Topics

Dear Twitter,

You have an opportunity to become the system of record for historical events by re-thinking trending topics.

I love the Twitter trending topics because they reflect the pulse OF THE PLANET on any given day. To date, the trending topics have worked very well for providing insights into most popular topics on any day going back several weeks (using the Twitter APIs). The fact that I can use a Twitter API (for example, http://dev.twitter.com/doc/get/trends/daily) to access the trending topics for a given day, makes Twitter a form of a system of record for the most important topics of conversation on any given day. However, trending topics are not without their shortcomings. Now and again we see that certain hashtag memes and other Twitter memes tend to displace topics related to events of historical importance from the list of trending topics. Because Twitter APIs only return a maximum of 20 trending topics per day, some topics of historical importance that do not make it into the top 20 are essentially lost. In order to preserve trending topics of historical importance and establish Twitter as a reliable system of record for topics of historical importance, there is a need to improve the sophistication of the trending topics. In addition to the current trending topics, I would like to propose the contextualization of trending topics into Trending Topic Categories. Categorizing trending topics into categories such as People, Politics, Sports, Entertainment, Technology, Memes, Finance etc gives the opportunity for trending topics that do not make it into the Top 20 to make it into the Top 20 of their respective categories. Today, we are losing a significant historical record as memes crowd out other historically significant trending topics and potentially depriving future historians, researchers and school kids alike from getting accurate information when they search for answers to the following: “What were the major topics of discussion in technology 50 years ago on March 23, 2011″. I do not think the trending topic “#100factsaboutme” will be very helpful at all.

Given your donation of the Twitter stream to the Library of Congress, my assumption is that you do indeed recognize that you are a system of record of one kind or another. Your meta-data, such as trending topics, has the potential to be used for public good. It has the potential to help future generations understand our generation at a much finer granularity than we have been able to understand previous generations. As I ask you to make this enhancement to trending topics, I do recognize that you are a business and that contextualized trending topics may not be part of your business objectives; that is why I would like to suggest that you work with volunteers (open source-type of collaboration model) who are passionate about putting a taxonomy on the world’s conversations for the purposes of posterity. I, for one, would love to partake and many others will. Putting the categorization of trending topics in the hands of volunteers will guarantee that categorized trending topics are free to the public in the same way trending topics are today.

By re-thinking your approach to trending topics as suggested, you have an opportunity to become an invaluable true system of record that stands to benefit future generations.

Sincerely,

Tom Chikoore

PS: If this is not the first time you have heard this request, I hope this letter finally tips the scale for you :)

March 12th, 2011 | Tags:

I am loving the new features in the new Foursquare 3.0 release. Being the big believer in the wisdom of the crowds that I am, I often rely on the Foursquare tips to help me navigate menus to find the best entrees each time I visit a restaurant. That is why I have been looking forward to using the new social recommendation feature in Fourquare 3.0 which is based is based on tips, to-dos and volume of check-ins. The recommendation feature is described in this excerpt from this Foursquare blog post:

For many, foursquare has been a great way to find out about the places your friends frequent (through check-ins) and learn about specific experiences to seek out (through tips and to-dos). For years we’ve wanted to build a recommendation engine for the real world by turning all the check-ins and tips we’ve seen from you, your friends, and the larger foursquare community into personalized recommendations.

This morning I was playing around with the social recommendation feature and observed that the recommendations are based on the popularity of a place. It looks like “popularity” is determined by the number of check-ins and tips. Unfortunately, Foursquare is not parsing the tips to determine content and context. Check out the following screen-shots for a Walgreens Pharmacy that Foursquare recommended:

Foursquare 3.0 Walgreens "recommendation"

Here is a Walgreens recommendation that came up as part of my search results. The tip below it caught my eye so I checked out the rest of the tips. See below.

Foursquare 3.0 Walgreens "recommendation" tips

Both tips for this Walgreens are negative.

For a recommendations, I would suggest that Foursquare parse the tips for sentiment. As a Foursquare recommendation service user, I would like the places that are recommended to me to be not only places that have a high volume of check-ins and tips but also a high volument of positive sentiment tips. If the algorithm is enhancement to include some sentiment analysis, then this Walgreens store would not have been recommended to me.

March 9th, 2011 | Tags:

Had a recent conversation with @arinewman about our SaaS experience during the Filtrbox days and it reminded of this blog post that I wrote last year after I counseled a local company on the SaaS delivery problems it was experiencing (unfortunately, like most posts, I started writing the post and it has remained the “Drafts” folder ever since)

As CTO of Filtrbox, I found myself primarily responsible for service delivery and customer experience instead of the traditional CTO responsibilities. That was as a result of a progressive lessons that I learned along the way about running a SaaS company. With the help of mentors, @slcaruso and @sether, I grew to appreciate good practices of running a successful SaaS offering (we were not always successful in reaching reach our goals but we a made a concerted effort to run the company using the the best SaaS practices). Many a blog posts have been written about SaaS from a technology and architecture point of view; in this blog post, I would like to share some fundamental aspects of SaaS that are often overlooked and often lead to unsuccessful SaaS implementations regardless of a solid technology or architecture.

Its a “Service” stupid
The following is a screen-shot of the description of the “Service Delivery” responsibility for my role as the CTO of Filtrbox:

Screen shot 2011-03-09 at 2.50.57 PM

The most important part of delivering “Software-as-as Service” is not the “Software” but the “Service”. In order to deliver SaaS successfully you have to first recognize that your service is essential to someone (if it was not, they would not be your customer). To your customer, you are just like the telephone, power or water company. There is a level of expectation that we have for the services delivered by these companies (disclaimer: this example may not be relevant in all parts of the world). When we turn on the faucet we “expect” water to come out regardless of the time day or holiday, we do not expect to check Twitter for service “updates” or explanations and in the event that there is service interruption, it is of the highest priority to the service company and is quickly resolved. When you analogize your company with these tried and true old school service companies and when you think of yourself that as a service company first, then the notion of “service first” becomes ingrained in the DNA of your company, your team, your products and your processes.

Customer Experience
If you are a SaaS company and the goals of your offering do not include the words “customer” or “service”, then you should not be delivering a SaaS offering. I would even go as far as saying that if the the description of roles on your team do not include the word “customer” and, “service” or “experience” , you are headed for the Deadpool. Understanding customer experience is of fundamental importance to SaaS delivery. Before you embark on a SaaS offering, go through the exercise of mapping the the experience that you want your customer to have when they use your service. What do you want the customer’s experience to be at every touchpoint with your company? While some touch-points are not necessarily directly tied to SaaS, it is important to account for them as well if you are to get the notion of “service first” ingrained in your company’s DNA. Out of this will come your service warranties (availability, service response times, customer response time, security etc)

Always On
If your service was not valuable to a customer, they would not be using it. Therefore deliver it like its valuable to someone. Users of a SaaS offering expect it to be “always on” (think of the phone, lights and water). Frankly I don’t really care about the technology and efficiency of how the water company gets the water into the pipe, they could be using a bunch of people pouring buckets into the pipe for all I care, my expectations is that when I turn on the faucet, water comes out. Your SaaS users have the same expectation. As an engineer, it pains me to say this, but SaaS users don’t really care about the beauty of your code, its cyclomatic complexity or any of that engineering stuff; they just want your product to work and meet their needs when they use it. That is all they expect. This is not say, you can get away with crappy code, in fact recognizing this has the opposite effect, it leads to better software, hardware, hosting and operations choices.

You are a “Service Delivery” Company
In order to deliver a “service” that is “always on”, the whole company from the top down has to have buy in into the the notion that you are actually a “Service Company” more so than a “Software Company”. The buy in is important because it leads to structuring the organization for service delivery right from the beginning. Recognizing that you are a service delivery company forces the company to provide adequate resources to service delivery related functions. It forces resource planning that values customer service, product development, hosting/operations resource equally.

Because most companies do not see themselves as “service delivery” companies, they often find themselves well staffed in engineering but severely understaffed in hosting/operations and customer service – a recipe for a short-lived SaaS operation. Once a SaaS offering is operational, if your company has engineers only, there is going to be very little engineering and innovation to be done because you engineers are going to spend their time supporting the system and the customers (I say this from experience). I’d recommend hiring a service administrator or service support person instead of an additional engineer because that they free up the engineering team to innovate and make progress on the product. Balance your resources accordingly, you are service company now.

Summary
Rather than be obsessed about the “software” aspects of SaaS, I strongly recommend that companies thinking of delivering SaaS offering undergo a midshift and think of themselves as “service” companies first. The above-mentioned aspects allow you to build the “service first” mentality into you company’s DNA. When you do that all the other software aspects will fall into place.

January 23rd, 2011 | Tags:

In my last blog post, I talked about managing my signal overload problem. Since then, I have been looking for a tool to help manage my signal overload problem. I have tried several tools and Summify is the one tool that I am using now. I have setup up my Summify account to aggregate the most important content items from my Twitter stream. Each day Summify send me a digest of the most important content items from Twitter stream. From what I can tell, Summify is using a combination of retweets and shares to figure out the most the top ranking content items in my social graph. I have verified whether the content items it suggest are really the most important and it all cases Summify was correct. However, the the results tend to be skewed towards high trending news items. I have not found any “nuggets” yet. While this is not a simple problem to solve, the guys at Summify have started on a good note. On days that I cannot go through my Twiter stream, I turn to Summify to catch up on the most important content items of the day.

July 8th, 2010 | Tags:

I have a signal overload problem.

At Filtrbox, we spent the better part of the last three years solving the information overload problem by separating the signal from the noise. With that problem yet to be completely solved, I am already dead smack in the middle of a signal overload problem.

Needless to say, I am used to a great signal because I developed and used Filtrbox for my content filtering. However,  recently my “Folksabox” (human version of Filtrbox powered by folks) , which is Twitter, has also started to produce ever-increasing large quantities of quality signal that is absolutely overwhelming and is now almost impossible to keep up with.  I credit my signal overload to the quality of content shared by people I follow on Twitter.  The majority of the people I follow are sharing thoughts, opinions and notions that they have put a lot of thought into, they are also sharing very valuable data/content (this may not reflect everyone’s experience on Twitter, I tend to follow people and organizations on Twitter who have an inherent understanding and appreciation of its value as an information dissemination/opinion sharing tool).

Too much signal has become a problem for me. As I write this post, I lament as I watch a steady stream of great content that I would love to read but I know is going to go unread because there is just too much of it and I don’t have enough time in the day to do so.  On a good day, I manage to read just 1% of the total amount of content that I would love to read. For me, this is creating an information poverty of a different kind. I am not well informed despite too much good information (try to figure that one out). Given the increase in the zettabytes of content being generated, this problem is bound to get worse – this is just the beginning.

How do we solve the problem of signal overload on our way to becoming SWIFs (super well-informed information freaks)? Until we, ordinary humans, have the means and capacity to absorb large amounts of data and information in a short time, we’ll settle for good ‘ol algorithmic solutions.  The solution lies not in filtering out signal further to get another uber-signal. The solution lies in the extraction of important data, facts and opinion from the signal in order to reduce the amount of information so that it can be human-consumable within a reasonable  amount of time.  Today, there are a few products that perform content summarization but like other NLP-related products (e.g. sentiment), none of them do it well and there is still a long way to go. Given that we are still a long ways, in my opinion, this one of the major “whats next” areas in information processing (are you listening future Techstars 2011 applicant). I hope we can start working on signal overload solutions soon because the problem is bound to get worse.

I will be speaking at the Bard Entrepreneurship Network meetup on June 30, 2010 at Jackson’s (map) in downtown Denver at 6:00 pm. I will be speaking on various startup and entrepreneurship topics.

The event is sponsored by the Bard Entrepreneurship Network (BEN) which is a network of entrepreneurs associated with the Bard Center for Entrepreneurship (which I attended several years ago).  Several of BEN’s members have founded vibrant startups in the Denver area.  Yes, Denver does  indeed have a up and coming startup community with a healthy diversification of ventures.   The University of Colorado at Denver Business School has for the better part of the last decade invested a lot of energy into cultivating entrepreneurship-focussed graduates and that investment has begun to pay off.  The University of Colorado at Denver’s Bard Center for Entrepreneurship and the Business School’s startup incubator have played a large role in contributing to the startup activity in the Denver area.  This is a great start, there is still a lot of work to be done; I would like to commend both the University of Colorado at Denver Business School and BEN for their contributions to the entrepreneurial community in the Denver area.

If you an entrepreneur in the Denver area and are looking to be part of the entrepreneurial community, I strongly recommend the Bard Entrepreneurship Network

Find more information about BEN here.

Find more information about the Bard Center here.

PS: For speaking engagement requests, contact me at tom [at] tomchikoore.com

March 26th, 2010 | Tags: ,

I am doing some research on technology startups and early stage companies in the Denver metro area (excluding Boulder). It is an analysis of tech startup activity in the area. As part of the research, I am compiling a list of all the technology startups and early stage companies in metro Denver. If you know of any tech startup companies in metro Denver or if you are one, please send me an email with the name of the company, website URL and a contact name (if possible). Please send it to tom AT tomchikoore DOT com or leave a comment on this post. That would be very helpful.

I will publish the results of my research here.

NOTE: The research is limited to the Denver metro area EXCLUDING Boulder. Boulder, I still love you though :)

Recently, I selected Spring Roo as my RAD tool of choice.  I use it for quickly churning out ideas into prototypes. It is my Java solution for the functionality that I have admired in Ruby On Rails. However, Spring Roo is still in its infancy. Its is just over a year old and still on its arduos joruney to maturity. One of the inadequacies of Spring Roos that I ran into right off the bat was the inability of Roo to work with an existing database.  In other words, Roo does not currently allow developers to start with a database, reverse engineer the schema into an ORM and build apps on top.  The ability to do this is Roo’s currently most requested feature. It is documented here as a Jira issue.

A couple of workarounds have been suggested to get around this problem. One of the workaorunds that I considered  is using Eclipse to generate entities from table using a JPA project.  However, this approach does not create Roo-specific annotation such as the @RooEntity,@RooToString and @RooJavaBean, all of which will have to be coded by hand. Given the inadequacoes of all the approaches, I came up with a method that has been working for me. I must say, I suggest this method ONLY if you have a few tables (and for non-production work). I can see this method turning into a laborious process if you have many tables; if that is your situation, you are probably better served going the Eclipse JPA project route.

(NOTE:  Ben Alex has indicated that the next version of Spring Roo will address Jira issue “ROO-435″)

Here is the process for creating a Spring Roo project using an existing database (the assumption here is that the reader is familiar with the creation of Spring Roo projects. If not, please take this excellent tutorial by Ben Alex first):

We are going to create a Directory project that allows us to look up people using a Person object.

Step 1: Create a database named “directory”. Create a table named “Person”. Insert a few rows into the Person table. I am using MySQL for the database but any database of your choice can work with this tutorial.

$ mysql -h localhost -u su -p
mysql> create database directory;
mysql> use directory;
mysql> CREATE TABLE Person (person_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,last_name VARCHAR(45) NOT NULL,first_name VARCHAR(45) NOT NULL,date_of_birth DATE NOT NULL,created_date TIMESTAMP NOT NULL,PRIMARY KEY (`person_id`));
mysql> insert into person (last_name, first_name, date_of_birth, created_date) values ('Winnfield','Jules','1967-06-07',NOW());
mysql> insert into person (last_name, first_name, date_of_birth, created_date) values ('Vega','Vincent','1971-04-15',NOW());
mysql> insert into person (last_name, first_name, date_of_birth, created_date) values ('Wallace','Marsellus','1970-01-01',NOW());
mysql> insert into person (last_name, first_name, date_of_birth, created_date) values ('Wolfe','Winston','1960-07-04',NOW());


mysql> select * from Person;
+-----------+-----------+------------+---------------+---------------------+
| person_id | last_name | first_name | date_of_birth | created_date        |
+-----------+-----------+------------+---------------+---------------------+
|         1 | Winnfield | Jules      | 1967-06-07    | 2010-03-19 15:33:31 |
|         2 | Vega      | Vincent    | 1971-04-15    | 2010-03-19 15:35:00 |
|         3 | Wallace   | Marsellus  | 1970-01-01    | 2010-03-19 15:36:52 |
|         4 | Wolfe     | Winston    | 1960-07-04    | 2010-03-19 15:37:19 |
+-----------+-----------+------------+---------------+---------------------+
4 rows in set (0.09 sec)
mysql> select * from Person;
+-----------+-----------+------------+---------------+---------------------+
| person_id | last_name | first_name | date_of_birth | created_date        |
+-----------+-----------+------------+---------------+---------------------+
|         1 | Winnfield | Jules      | 1967-06-07    | 2010-03-19 15:33:31 |
|         2 | Vega      | Vincent    | 1971-04-15    | 2010-03-19 15:35:00 |
|         3 | Wallace   | Marsellus  | 1970-01-01    | 2010-03-19 15:36:52 |
|         4 | Wolfe     | Winston    | 1960-07-04    | 2010-03-19 15:37:19 |
+-----------+-----------+------------+---------------+---------------------+
4 rows in set (0.09 sec)

mysql> exit;

Step 2: Create an empty directory named “directory”, cd to it and fire up Roo.

$ mkdir directory
$ cd directory

$ roo
    ____  ____  ____
   / __ \/ __ \/ __ \
  / /_/ / / / / / / /
 / _, _/ /_/ / /_/ /
/_/ |_|\____/\____/    1.0.2.RELEASE [rev 638]

Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.
roo>

Step 3: Create the Roo project with a top level package of “com.tomchikoore.examples.directory”


roo> project --topLevelPackage com.tomchikoore.examples.directory
Created /Users/tom/Documents/workspace-sts-2.3.1.RELEASE/directory/pom.xml
Created SRC_MAIN_JAVA
Created SRC_MAIN_RESOURCES
Created SRC_TEST_JAVA
Created SRC_TEST_RESOURCES
Created SRC_MAIN_WEBAPP
Created SRC_MAIN_RESOURCES/META-INF/spring
Created SRC_MAIN_RESOURCES/META-INF/spring/applicationContext.xml
Created SRC_MAIN_RESOURCES/META-INF/spring/log4j.properties

Step 4: Install a JPA provider and database. Since I created the Person table in a MySQL database, I am going to specify MYSQL as my database.

roo> persistence setup --provider HIBERNATE --database MYSQL --databaseName directory --userName su
Created SRC_MAIN_RESOURCES/META-INF/persistence.xml
Created SRC_MAIN_RESOURCES/META-INF/spring/database.properties
please enter your database details in src/main/resources/database.properties
Managed SRC_MAIN_RESOURCES/META-INF/spring/applicationContext.xml
Managed ROOT/pom.xml

Step 5: Disable the auto database creation in the persistence.xml file

Roo sets up the persistence settings so that the database is created when the application run. Since your database already exists, turn this setting off by going to this file:

SRC_MAIN_RESOURCES/META-INF/persistence.xml

and comment this line:

<property name="hibernate.hbm2ddl.auto" value="create"/>

So that it looks like this:
<!-- <property name="hibernate.hbm2ddl.auto" value="create"/> -->

Save the file and close.

Step 6: Create the Person entity.  This is the Java object representation of a Person row entry in the database

IMPORTANT: The important thing to understand here is that Roo creates two fields by default, an identifier “id” field and a versioning “version” field.  The problem here is that our Person table has neither of those columns (I purposefully created the Person table without either field, especially the “id” field which I named “person_id” so that I can clearly make this point). In my case, I have a schema that has been in production for years and I do not want to start adding columns to our the table on because they are required by a RAD tool, that will turn out to be a bad decision once the next RAD tools comes along.

Therefore what I want to do is  instruct Roo NOT to create a default “id” and a “version” fields.   Unfortunately, I cannot instruct Roo not to create a “version” field  at this step, I can only do it at a later step. At this step, I can only instruct Roo not to create a default “id” field by instructing it to use a different field for an “id” field. So I am going to go ahead an instruct Roo to create a Person entity WITHOUT the default identifier field named “id” but instead use the “person_id” field as the identifier field:

roo> entity --class ~.model.Person --identifierField person_id --identifierColumn person_id  --table Person
Created SRC_MAIN_JAVA/com/tomchikoore/examples/directory/model
Created SRC_MAIN_JAVA/com/tomchikoore/examples/directory/model/Person.java
Created SRC_MAIN_JAVA/com/tomchikoore/examples/directory/model/Person_Roo_Entity.aj
Created SRC_MAIN_JAVA/com/tomchikoore/examples/directory/model/Person_Roo_ToString.aj
Created SRC_MAIN_JAVA/com/tomchikoore/examples/directory/model/Person_Roo_Configurable.aj

Step 7: Add entity fields

IMPORTANT:  This is the most important step when creating the entity because it involves reverse-engineering the database table schema into entity fields. This is the functionality that is currently lacking in Roo. For this step I am going to use a script that I found in the Spring Roo forums; I have made several enhancements to the script to to make it usable. The script introspects the databse schema and generates Roo entity fild creation commands.

The first step is to run the script to create the Roo entity field creation commands.  In a separate window log back in to MySQL and run the following script:

mysql> select concat('field ',
elt(
field(data_type,'int' ,'varchar','bit' ,'timestamp','datetime', 'date', 'tinyint'),
'number','string' ,'boolean','date','date','date','number'),' --fieldName ',column_name,if (is_nullable='NO',' --notNull ',' '),
if(character_maximum_length is not null,concat(' --sizeMax ',character_maximum_length,' '),''),
elt(
field(data_type,'int' ,'varchar','bit' ,'timestamp','datetime','date', 'tinyint'),
'--type java.lang.Integer','--type java.lang.String' ,'--type java.lang.Boolean','--type java.util.Date','--type java.util.Date','--type java.util.Date','--type java.lang.Integer')
) from information_schema.columns cols where table_name='Person' and table_schema='directory';
+-----------------------------------------------------------------------------------------------+
| field number --fieldName person_id --notNull --type java.lang.Integer                         |
| field string --fieldName last_name --notNull  --sizeMax 45 --type java.lang.String            |
| field string --fieldName first_name --notNull  --sizeMax 45 --type java.lang.String           |
| field date --fieldName date_of_birth --notNull --type java.util.Date                          |
| field date --fieldName created_date --notNull --type java.util.Date                           |
+-----------------------------------------------------------------------------------------------+

5 rows in set (0.02 sec)

The second step is to execute the entity field commands generated by the script in the step above at the Roo comand line (go back to the Roo command window):

IMPORTANT: DO NOT RUN THE FIRST COMMAND. That is because the “person_id” has been specified to be the identifier in Step 6. If you create it here again, you will get duplicate field errors.

roo> field number –fieldName person_id –notNull –type java.lang.Integer

roo> field string –fieldName last_name –notNull –sizeMax 45 –type java.lang.String

roo> field string –fieldName first_name –notNull –sizeMax 45 –type java.lang.String

roo> field date –fieldName date_of_birth –notNull –type java.util.Date

roo> field date –fieldName created_date –notNull –type java.util.Date


Step 8: Perform JUnit Integration test

roo> test integration

Step 9: Create the web tier

roo> controller scaffold ~.web.PersonController

Step 10: Add finders

roo> finder add –finderName findPeopleByLast_nameLike

roo> finder add –finderName findPeopleByFirst_nameLike

Step 11: Remove the default “version” field

In Step 6, I mentoned that Roo creates two default fields for each entrity, the idntifier “id’ field and the versioning “version” field. In step 6 we were able to instruct Roo to use the “person_id” field instead of the default “id” field for the default indentifier.  At this step we are going to instruct Roo not to use the “version” field.  To do this, we have to change the @RooEntity annotation in the Person.java class. In this example, the source for  the Person.java class is located at:

SRC_MAIN_JAVA/com/tomchikoore/examples/directory/model/Person.java

Open this source file and locate the following line (notice the identifier overrides that we set in Step 6):

@RooEntity(identifierField = “person_id”, identifierColumn = “person_id”, finders = { “findPeopleByLast_nameLike”, “findPeopleByFirst_nameLike” })

Add versionField = “”, such that the line looks as follows:

@RooEntity(identifierField = “person_id”, identifierColumn = “person_id”, versionField = “”, finders = { “findPeopleByLast_nameLike”, “findPeopleByFirst_nameLike” })

Save the file and close.

Step 12: Import the project into Eclipse

(I am going to use Eclipse/STS for the sole purpose of being  consistent with the original Spring Roo tutorials so that I don’t throw off novices)

roo> perform eclipse

After this command completes, open up Eclipse or STS and import (File -> Import -> Existing Projects into Workspace) the “directory” project.

Step 13: Run web aplication

Deploy the application war and go to http://localhost:8080/directory

When you click on “List all People”, you should see the following:

"List all People" results

"List all People" results

Thats it!!