Monday, December 20, 2010

Two ways to build a CRM QueryExpression

I always wondered what FetchXML was useful for and I’m starting to see its value.  I ran into a wall with the new Linq based Advanced Developer Extensions and have reverted back to the “stone-age” web services.  Having to build QueryExpressions by hand led me to the discovery that I could actually use FetchXML syntax to build my expressions by using a FetchXmlToQueryExpressionRequest Combining this with Stunnware’s FetchXML builder might be even faster once you get the hang of it.  Certainly makes debugging a complex join query snappy.

 

Check out these two ways to get the exact same dataset:

 

        private static void FetchAppsToProcess(Microsoft.Crm.SdkTypeProxy.CrmService crmWebSvc)

        {

            string fxml =

                @"<fetch mapping='logical' count='50' version='1.0'>" +

                " <entity name='new_transistionapplication'>" +

                "       <attribute name='new_transistionapplicationid' />" +

                "       <filter>" +

                "             <condition attribute='createdon' operator='lt' value='9/17/2010' />" +

                "             <condition attribute='new_lastname' operator='eq' value='Smith' />" +

                "       </filter>" +

                " </entity>" +

                "</fetch>";

 

            //string xmlResult = crmWebSvc.Fetch(fxml);

            FetchXmlToQueryExpressionRequest fxmlReq =

             new FetchXmlToQueryExpressionRequest() { FetchXml = fxml };

            FetchXmlToQueryExpressionResponse expression =

             (FetchXmlToQueryExpressionResponse)crmWebSvc.Execute(fxmlReq);

 

            var request = new RetrieveMultipleRequest { Query = expression.Query, ReturnDynamicEntities = true };

            var response = (RetrieveMultipleResponse)crmWebSvc.Execute(request);

 

        }

 

        private static void GetAppsToProcess(Microsoft.Crm.SdkTypeProxy.CrmService crmWebSvc)

        {

            List<string> reqBoards = new List<string>();

 

            var con = new ConditionExpression

            {

                AttributeName = "createdon",

                Operator = ConditionOperator.LessThan,

                Values = new object[] { DateTime.Parse("9/17/2010") }

            };

 

            var conName = new ConditionExpression

            {

                AttributeName = "new_lastname",

                Operator = ConditionOperator.Equal,

                Values = new[] { "Smith" }

            };

 

            var filter = new FilterExpression();

           

            filter.AddCondition(con);

            filter.AddCondition(conName);

            filter.FilterOperator = LogicalOperator.And;

           

 

            // The Entity returning the results

            var expression = new QueryExpression

            {

                EntityName = "new_transistionapplication",

                Criteria = filter

            };

           

            expression.ColumnSet = new ColumnSet(new string[] { "new_transistionapplicationid", "new_requestedboardappointments" });

 

            var request = new RetrieveMultipleRequest { Query = expression, ReturnDynamicEntities = true };

            var response = (RetrieveMultipleResponse)crmWebSvc.Execute(request);

        }

Friday, December 17, 2010

Installing SSRS - SocketException: No such host is known

I just about went crazy trying to do a SSRS install on a named instance.  Every time I ran through the database configuration, I got this error.

System.Net.Sockets.SocketException: No such host is known

   at System.Net.Dns.GetAddrInfo(String name)

   at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6)

   at System.Net.Dns.GetHostEntry(String hostNameOrAddress)

   at ReportServicesConfigUI.RSDatabase.IsLocalDbServer(String dbServer)

   at ReportServicesConfigUI.RSDatabase.GrantRSConnectionRights()

   at ReportServicesConfigUI.RSDatabase.CreateNewDatabase()

Turns out, this issue has a simple, but hidden workaround.  Specify the Server Name as outlined on this blog post:

 

It seems if you use a connection format like “ServerName\InstanceName,Port”, then SSRS Configuration manager is able to connect without requiring the SQL Browser service.

 

Without SQL Browser service running (either shutdown or blocked behind the firewall), SSRS Configuration Manager still does not work with “ServerName,Port\InstanceName” format or via SQL Aliases.

 

Tuesday, December 14, 2010

Daddy Bread

After reading the article, Artisian Bread in Five Minutes a Day, I have been making about 1-2 loaves and a pizza every week.  My kids have dubbed it, “Daddy bread” and it goes fast!  As you might imagine we go through a decent amount of flour, so we buy 25lbs bags at Costco.  This picture of six coffee cans is the latest supply of flour.  I can almost smell the bread cooking!

Monday, December 13, 2010

How to Hide System Views in CRM 4.0

This post could also be titled, how to pass configuration to CRM Plugins.  I found a sample solution in the MSDN Code Gallery but the installation details were left to the imagination.  Fortunately another person posted on how to hard-code a plugin with the Assembly Registration information needed.  First you register the assembly, then add a step with this information:

 

Message: RetrieveMultiple
Primary Entity: savedquery
Stage of Execution: Post Stage
Execution Mode: Synchronous

Unsecure Configuration: <the XML from the sample config file>

 

There was a problem with the code from the gallery in that the constructor for plugins seems to have changed.  Plugin constructors require two string parameters as detailed in this blog post.  The first is the “unsecure configuration” and the second is the “secure configuration”.

 

The nice thing is that the views are hidden as soon as you “Update” the Step Registration.  No need to restart CRM or anything fancy. 

 

You can download the source of my plugin here (6 Kb zip) (you may have to update the references to the SDK dlls).

Thursday, December 2, 2010

How to set a recipient in the CRM Send Email window via URL querystring

I need to let the user edit the email before sending, so email templates seem to be the best choice.  I love how CRM set the Regarding to my current entity.  In addition I wanted to be able to set the To: field based on a contact record.

 

MSDN - URL Addressable Forms and Views

and here:

Working With All MS CRM DataTypes In Javascript

and ultimately, I figured out the querystring parameters that allow you set a PartyList attribute (To is a PartyList - thanks to Stunnware tool for that detail).  So by adding these parameters to the original Send E-Mail link, the email opens pre-populated:

&partytype=2&partyname=John%20Doe&partyId={1FF3C7A9-D8BC-DF11-8337-005056BC7B56}

 

Tuesday, November 30, 2010

Microsoft CRM SDK Advanced Developer Extensions Linq Cache Issue

There has been a significant improvement in the XRM Linq provider in the 4.0.13 SDK that allows you to specify how you want your DataContext to use caching.  One thing I noticed was I had to change my default Service to use the disabled cached to get it to use the Microsoft.Xrm.Client.Services.OrganizationService which is the “un-cached” service. 

 

There seems to be a noticeable speed improvement for the initial connection time and I don’t see any difference in query time using the un-cached service.

 

Sample web.config entries (2kb XML file)

Monday, November 22, 2010

Checking Java memory usage on a Linux server

A customer reported slowness in a production system, so I ran the following commands to check the state of the memory usage (since recently we had out-of-memory errors):

 

ps -ef|grep java

jmap -heap <pid>

 

 

The output:

 

Attaching to process ID 1715, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 14.0-b16

 

using thread-local object allocation.

Parallel GC with 2 thread(s)

 

Heap Configuration:

   MinHeapFreeRatio = 40

   MaxHeapFreeRatio = 70

   MaxHeapSize      = 2015363072 (1922.0MB)

   NewSize          = 2686976 (2.5625MB)

   MaxNewSize       = 17592186044415 MB

   OldSize          = 5439488 (5.1875MB)

   NewRatio         = 2

   SurvivorRatio    = 8

   PermSize         = 21757952 (20.75MB)

   MaxPermSize      = 134217728 (128.0MB)

 

Heap Usage:

PS Young Generation

Eden Space:

   capacity = 368246784 (351.1875MB)

   used     = 259936376 (247.89464569091797MB)

   free     = 108310408 (103.29285430908203MB)

   70.58754815900849% used

From Space:

   capacity = 11534336 (11.0MB)

   used     = 11502000 (10.969161987304688MB)

   free     = 32336 (0.0308380126953125MB)

   99.71965443004261% used

To Space:

   capacity = 12451840 (11.875MB)

   used     = 0 (0.0MB)

   free     = 12451840 (11.875MB)

   0.0% used

PS Old Generation

   capacity = 122290176 (116.625MB)

   used     = 76169032 (72.64044952392578MB)

   free     = 46121144 (43.98455047607422MB)

   62.285487265959944% used

PS Perm Generation

   capacity = 88211456 (84.125MB)

   used     = 39361424 (37.53797912597656MB)

   free     = 48850032 (46.58702087402344MB)

   44.62166909477155% used

 

Monday, November 15, 2010

Severn River Cruise on the Mobjack Bay

The weather around Veterans Day 2010 was absolutely stunning; Crystal clear blue skies, 65F, and a fresh 15-20Kts out of the NE.  I got permission to take the Alberg 22 docked near Yorktown, VA for a two-day solo cruise.  With the wind creating Small Craft Advisory conditions, I was thinking of heading NW up the York see West Point from the water and then find a little creek to tuck into.  As I headed out into the York, I was surprised to find ideal flat water conditions.  I realized there was quite a bit of protection from the land, but it was so tempting to head east…so that’s what I did.  As I got nearer to the Guinea flats, the wind picked up.  As I cleared the land and the full fetch of the Mobjack was felt, the waves were a short steep 3-5’ seas.  The Alberg could really have used a reef at this point, but easing the sheet just a little helped with the weather helm.  The boat kept a stead 4.5-5 kts with a nice motion.

 

Being a mid-November Thursday, there weren’t a lot of boats on the wather, so I was relieved to see a 50’ M/V and a little later, I saw what looked like two boats sailing really close together.  Later this turned out to be a gaff-rigged schooner that I followed into the Severn River.  I headed up the North branch and noticed what looked like a large sailboat behind a spit of land.  The tide was about 3’ above normal so it seemed like my 3’ draft should have no trouble getting back there.  I was rewarded with a beautiful little anchorage that was surrounded by some gorgeous Matthew’s County properties.

 

I didn’t have too many chances to snap pictures while sailing (solo SCA kept my attention), but the anchorage afforded an amazing sunset:

http://picasaweb.google.com/snyd1437/ChesapeakBay#

Saturday, November 6, 2010

IIS 404 error!!! It's now 2am...thank you very much Microsoft security team

http://support.microsoft.com/kb/315122

 

By default, when IIS is installed on any version of the Windows Server 2003 family, IIS only serves static content (HTML).

Thursday, October 28, 2010

Creating a WebReference to a specific CRM tenant

Sometimes it’s the little things that can take forever to figure out.  I inherited a web application that connected to a CRM tenant and after adding a few new attributes to CRM, I needed to update my WebReference.  Unfortunately the last developer had been working in a VPC so my WebReference that I had set to the CRM server resulted in the proxy classes that were “generic” and did not contain my customizations.  I remembered doing this before, but it had been awhile so I had to search for the answer (again):

 

<add key="crmservice.CrmServiceWsdl" value="http://<CRM Server>/mscrmservices/2007/crmservice.asmx?uniquename=<tenant>"/>

Tuesday, October 5, 2010

Setup a domain user account as the CrmAppPool identity

It was difficult to find the documentation on exactly which groups / policies the CrmAppPool identity needed when changing from Network Service to a domain user account.  Fortunately I found this Microsoft KB which gives you step-by-step instructions (note, I removed the CRM 3.0 portions) and it worked on the first try:

 

1.     Include the domain account user in the following groups in Active Directory:

o    The Domain Users Active Directory group

o    The PrivUserGroup

o    The SQLAccessGroup

To do this, follow these steps:

d.             Log on to a server as a user who has the Domain Admin rights or the rights to update these groups.

e.     Right-click the Domain Users group in Active Directory, and then click Properties.

f.      In the Group name box, type the name of the user who is running the CRM Application Pool, and then click OK two times.

g.     Repeat steps b and c for the PrivUserGroup group and for the SQLAccessGroup group.

If you have more than one Microsoft Dynamics CRM deployment installed, multiple groups exist in Active Directory. To determine the groups that you want to update, follow these steps.

For Microsoft Dynamics CRM 4.0

h.             Run the following SQL statement against the MSCRM_config database:

select id, friendlyname from organization

i.              Note the GUID. For example, the GUID may be C8AB1D52-9383-4164-B571-4C80D46674E3 Org Name.

j.      Find the PrivUserGroup group and the SQLAccessGroup group in Active Directory. The group name contains the GUID that you noted in step b.

2.     Include the domain account user in the following groups in the Microsoft Dynamics CRM server:

o    The local IIS_WPG group

o    The local CRM_WPG group

Note The domain account user must have the following local user rights:

o    The Impersonate a client after authentication right

o    The Log on as a service right

To do this, follow these steps:

d.     In the Microsoft Dynamics CRM server, click Start, point to Administrative Tools, and then click Local Security Policy.

e.     Expand Local Policies, and then click User Rights Assignment.

f.      Right-click Impersonate a client after authentication, and then click Properties.

g.     Click Add User or Group.

Note You may have to click Location to select the domain instead of the local computer.

h.     In the Group name box, type the name of the user who is running the CRM Application Pool, and then click OK two times.

i.      Repeat steps 2c through 2e for the Log on as a service right.

3.     Restart Internet Information Services (IIS). To do this, click Start, click Run, type IISRESET, and then click OK.

 

Tuesday, August 17, 2010

Connect to CRM Web Service using impersonation

My Dev and Test servers live in two different domains and I am developing an external “portal” for public users to interface with CRM using web services. I am developing locally, but my CRM server is on a different domain, so I need to use a different domain user to connect to the web service. I am using the new SDK and the connection string was easy to change from “Integrated” to “AD”:

<add name="Crm"

connectionString="Authentication Type=AD;Server=http://CRM/Org1;User ID=USA\user1;Password=pass1"

/>

But I also need to use the MetadataService to lookup some picklist values and that requires connecting the “old school” way. We were already using the Crm connection string to configure the MetadataService, so I just needed to check the Auth type and grab the User ID and Password:





public MetadataService GetMetadataServiceForConnString()
{
string serverPath = GetConfigAttribute("server=http://");
string[] serverPathParts = serverPath.Split('/');
string connServer = serverPathParts[0];
string connOrgName = serverPathParts[1];
string username = null;
string password = null;
string domain = null;
if (GetConfigAttribute("authentication type=").ToLower() == "ad")
{
// need to use active directory credentials
string[] usernameParts = GetConfigAttribute("user id=").Split('\\');
domain = usernameParts[0];
username = usernameParts[1];
password = GetConfigAttribute("password=");

}
return GetMetadataService(connServer, connOrgName, username, password, domain);
}

private string GetConfigAttribute(string searchString)
{
string connCrm = System.Configuration.ConfigurationManager.ConnectionStrings["Crm"].ConnectionString;
int pathPadding = searchString.Length;
int pathStart = connCrm.ToLower().IndexOf(searchString.ToLower()) + pathPadding;
int pathLength = connCrm.IndexOf(";", pathStart);
if (pathLength == -1)
pathLength = connCrm.Length;
pathLength -= pathStart;
return connCrm.Substring(pathStart, pathLength);
}

public MetadataService GetMetadataService(string server, string organizationName, string username, string password, string domain)
{
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = AuthenticationType.AD; //Active Directory
token.OrganizationName = organizationName;
MetadataService service = new MetadataService();
service.Url = string.Format("http://{0}/mscrmservices/2007/MetadataService.asmx", server);
if (username == null)
{
service.UseDefaultCredentials = true;
}
else
{
service.UseDefaultCredentials = false;
System.Net.ICredentials WebServiceCredentials =
new System.Net.NetworkCredential(username,password,domain);
service.Credentials = WebServiceCredentials;
}
service.PreAuthenticate = true;
service.CrmAuthenticationTokenValue = token;
return service;
}


Thursday, August 5, 2010

Use xp_cmdshell and BCP to Export SQL Server data to CSV

This article describes how to use xp_cmdshell and BCP to export data to CSV.  One problem I ran into was the error “Unable to open BCP host data-file”.  This turned out to be a file permission issue.  I had to give NETWORK SERVICE (the local account that runs my SQL Server service) Full Access rights to the queryout directory.  I also had to use the –S flag to specify which SQL Instance (my server has two) to connect to:

 

EXEC xp_cmdshell 'bcp "SELECT * FROM <my database>.dbo.account" queryout "D:\queryout\bcptest.txt" -T -S "<my server>\<my instance>" -c -t,'

 

 

Get a list of all the tables in a SQL 2005/2008 database

I thought this SQL 2005/2008 tip was very cool.  This gets a list of all the tables in my database:

 

SELECT [name] FROM <my database>.sys.tables;

 

Wednesday, July 21, 2010

Grant Permission for SQL User for Membership Provider using Database Role

The SQL User connecting to your Membershp Provider database (default named aspnetdb) should have the following database role:

aspnet_Membership_FullAccess

 

Otherwise you will get the following error:

EXECUTE permission denied on object 'aspnet_CheckSchemaVersion', database 'aspnetdb', schema 'dbo'.

Connection String for Membership Provider using a Trusted Connection over TCP/IP on a specific Port

<add name="LocalSqlServer"

  connectionString="Data Source=192.0.0.1,2116;

                    Network Library=DBMSSOCN;

                    Initial Catalog=aspnetdb;

                    Integrated Security=SSPI;"/>

 

Tuesday, July 20, 2010

Using data binding with Eval to set TemplateField button Visible property

I needed to conditionally hide a delete button in a GridView. This data binding expression did the trick:


<asp:ImageButton ID="ImageButton1" runat="server" CausesValidation="False"
CommandName="Delete" ImageUrl="~/_Images/cross.png" Text="Delete"
Visible='<%# ((string)Eval("statuscodeLabel") == "Draft") %>' />

I also ran across this little beauty that calls a DAL class to do a check against the database (the data is hopefully cached):



<asp:HyperLink ID="lnkCert" runat="server"
Visible='<%# SomeDAL.UserCanDoSomething(CType(Container.DataItem, System.Data.DataRowView).Item("Code").ToString()) %>'
NavigateUrl='<%# Eval("ID", "~/forms/AgencyForm.aspx?pid={0}&mode=cert") %>'>
<img src="../images/tick.png" alt="Certify Agency Data" /></asp:HyperLink>

Saturday, July 17, 2010

Pride goeth before a fall


I assure you...this did not end well.

Friday, July 16, 2010

Using CRM Advanced Developer Extensions to Add Attachment to Contact

This code sample is straight from MSDN, but it is so often used, I wanted to make sure I kept it handy:

 

// Add a note with a document attachment to the contact's record.

var attachment = File.OpenRead("capture.png");

var data = new byte[attachment.Length];

attachment.Read(data, 0, (int)attachment.Length);

 

var note = new Xrm.annotation()

{

  subject = "Note subject...",

  notetext = "Note Details....",

  Contact_Annotation_id = contact.contactid,

  objecttypecode = "contact",

  documentbody = Convert.ToBase64String(data),

  filename = Path.GetFileName(attachment.Name),

  mimetype = "image/png"

};

crm.AddToannotations(note);

crm.SaveChanges();

 

 

Friday, July 9, 2010

Retrieve CRM Entity's Picklist using MetadataService

This method returns a NameValueCollection of picklist items. CrmHelper is similar to the SDK utility sample.




public NameValueCollection GetAgencyRelationshipTypePicklist()
{
CrmHelper helper = new CrmHelper();

NameValueCollection picklist = new NameValueCollection();

RetrieveAttributeRequest attribReq = new RetrieveAttributeRequest();
attribReq.EntityLogicalName = "new_agencycontact";
attribReq.LogicalName = "new_agencycontacttype";
attribReq.RetrieveAsIfPublished = true;

MetadataService service = helper.GetMetadataService();

RetrieveAttributeResponse attribResp = service.Execute(attribReq) as RetrieveAttributeResponse;

PicklistAttributeMetadata listData = attribResp.AttributeMetadata as PicklistAttributeMetadata;

foreach (Option item in listData.Options)
{
picklist.Add(item.Value.formattedvalue, item.Label.UserLocLabel.Label);
}

return picklist;
}

Use JavaScript to hide an ASP.Net Button

To be 508 compliant, my page must allow users to select items from a drop-down list with JavaScript disabled, so I added a “select” button (called btnAgSelect) next to the list.  When JS is enabled, I do not want the button to be visible, so I used this in my Page.Load() event:

 

ScriptManager.RegisterStartupScript(

  this ,this.GetType(),

  "", "document.getElementById('" +

  btnAgSelect.ClientID + "').style.visibility='hidden';",

  true);

Saturday, July 3, 2010

Windows XP Standby Wakes Up

I got a new work laptop that I typically left on Standby, but it kept waking up in the middle of the night and draining the battery.  I assumed it was the NIC’s Wake-On-LAN setting so I disabled the following setting (note the OS warning that someone had obviously ignored) using Hardware Manager (System – Hardware tab):

 

 

 

 

Friday, June 11, 2010

Finding CRM 4.0 Entities with Attachments by Querying annotationBase Table

I needed to find all of the inactive records for an entity that had documents attached:

 

SELECT COUNT(*)
FROM   new_myEntityBase t
       JOIN annotationBase ab
         ON t.myentityid = ab.objectid
WHERE  statecode = 1 

Tuesday, May 11, 2010

Move Flex Alert.show on the screen

I have a tall Flex application that uses Alert.show( ) to display error messages.  This created problems when the error messages were centered on the screen, but not visible when the screen was at an extreme scroll position (top or bottom).  To solve this, I capture the MouseEvent and use it to set the Alert’s “Y” position.  Note this code did not work UNTIL I used the PopUpManager.centerPopUp prior to moving:

 

var errorMsg:Alert = Alert.show(errmsg,"Error", Alert.OK, this);

PopUpManager.centerPopUp(errorMsg);

 

var mousePt:Point = new Point(event.localX, event.localY);

mousePt = event.target.localToGlobal(mousePt);

errorMsg.move(errorMsg.x, mousePt.y - 50); // try to vertical center it at button

Tuesday, May 4, 2010

Compiling the CRM SDK CrmServiceUtility Class without Web References

According to Shan’s Blog post Using CRM SDK Instead of Web References, it is often preferable to use the SDK classes instead of the proxy classes generated when you add web references. Using the CrmServiceUtility class found in the 4.0 SDK in the \server\reference\cs folder is a perfect case in point. The way the code is written, you can compile it without a web reference simply by adding references to Microsoft.Crm.Sdk.dll, Microsoft.Crm.SdkTypeProxy.dll, and System.Web.Services and two using statements:

using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.SdkTypeProxy.Metadata;

Thursday, March 11, 2010

Google Maps and Flex are beautiful together

All I can say is WOW! Working with Google Maps in ActionScript is SOOOO much easier than HTML/JavaScript. In 5 minutes I had a working map and in 20 minutes of Google examples I had this:

I am sold.

Sunday, February 28, 2010

EveryTrail.com GPS Visualizer

I went for a mountain bike ride today (the trails are finally dry enough) and I was packing my Holux GPS to record the trek. I was running the new GPS Sport Tracker softare on my Windows Mobile 6.0 phone and the logs are in GPX file format. I found EveryTrail.com that will create a Flash animation of your GPX trip:

45 Minutes in Powhite


Map your trip with EveryTrail

Wednesday, February 24, 2010

Windows Mobile GPS Sport Tracker Software

I just discovered an excellent free (donations accepted) GPS software for Windows Mobile phones called GPS Sport Tracker.  It has amazing features for running, biking, hiking, boating and probably many other things.  I can’t wait to get this in the boat and fine tune the sail adjustments.  The features I particularly like are:

  • Speed in 1/10s of MPH
  • Distance travelled
  • Average/Max speed
  • Elevation change
  • Data logging to GPX file format
  • Maps of your track
  • Profile of your elevation

This is fantastic work!

 

Tuesday, February 23, 2010

New in Tomcat 6.0.19 - Realm lock-out feature

NOW they tell me.  Man it pays to RTFM...

http://www.jeremythomerson.com/blog/2008/11/apachecon-securing-apache-tomcat-for-your-environment/

New in 6.0.19 [the] LockOut realm - it wraps around standard realms and provides a lock-out mechanism for multiple failed attempts for the same user.  With this, there will also be the ability to have multiple realms for authentication - if any match, you get access - so you could use, for example, a tomcat users file for admins and a JNDI realm for users.

Full details here:
http://tomcat.apache.org/tomcat-6.0-doc/config/realm.html

You just wrap this around your existing realm (JDBC in our case).  I got this working and it will serve as a "backup" to my custom login attempts table.  The LockOut realm will prevent a brute force attack that hits the JAAS servlet directly.

Monday, February 22, 2010

SQL that return 1 or more rows, but is never empty

The alternate title for this post is "how I worked around the Spring JdbcTemplate queryForObject method throwing an EmptyResultDataAccessException when the query returned zero rows", but that didn't seemed a little verbose.

I added a SELECT 0 as a table source and joined to that to ensure there would always be one row:


SELECT Coalesce(i.UserID, 0) UserID, Coalesce(i.Password, '') Password, Count(a.UserID) Attempts
FROM (SELECT 0 AS id) mstr LEFT JOIN
(SELECT 0 AS id, UserID, UserName, Password FROM User WHERE UserName = 'Scooby') i ON mstr.id = i.id
LEFT JOIN UserAttempts a ON i.UserID = a.UserID AND LastAttempt > 1266602785
GROUP BY i.UserID,i.Password

Using Spring JdbcTemplate to queryForObject example

I needed to make a quick query to check some data before inserting a new record. The queryForObject allows you to create an inner RowMapper class to handle the ResultSet…in this case, I needed to return two integers so I mapped the results to an integer array with two elements:


JdbcTemplate springTemplate = new JdbcTemplate(this.currDs);
int[] user = springTemplate.queryForObject(
"select UserID, count(*) from t_actor where orgID = ?",
new Object[]{new Long(1212)},
new RowMapper<int[]>() {

public int[] mapRow(ResultSet rs, int rowNum) throws SQLException {
int[] user = new int[2];
user[0] = rs.getInt(0);
user[1] = rs.getInt(1);
return user;
}
});

Friday, February 19, 2010

Adding new folders in Eclipse


I discovered a great feature/shortcut for adding new folders in Eclipse. Java/Flex packages sometimes have very deep folder structures which are a bit of a pain to recreate by hand. The good news is Eclipse will create the folder structure in one fell swoop if you enter it. Here's what I do: I find the folder in Windows Explorer and copy the location (e.g. com\adobe\crypto ) and paste it into the new folder dialog and viola!

Wednesday, February 10, 2010

Eclipse WTP Axis2 Web Service Tutorial Hints

I have attempted to follow this Axis2 Tutorial and it has been painful.  I will attempt to ease other’s pain by providing the mistakes that I made to prevent others from making the same…

When I got this error:

ClassDefNotFoundException org.apache.http.HttpResponseFactory

It was because I was using Axis2 ver 1.5.1.  When I switched to 1.4.1 it was gone.

The tutorial says that opening http://localhost:8080/MyProject should display the Axis2 start page, but I found another Axis2 tutorial that said there was a bug and you actually needed to use:

http://localhost:8080/MyProject/axis2-web/index.jsp

 

Tuesday, February 9, 2010

Flex mx:Label htmlText and Font color behaviors

I just discovered a few qwerks with the Flex Label’s htmlText property that I thought were worth passing along.

First off, Labels are limited to one line, so the default behavior of the <mx:htmlText> <![CDATA[ will not display:

<mx:Label>

      <mx:htmlText>

            <![CDATA[

                  <font color="Red">*</font> indicates required field.

                  ]]>

      </mx:htmlText>

</mx:Label>

Once I consolidated the the CDATA lines into one it displayed:

<mx:Label>

      <mx:htmlText>

            <![CDATA[ <font color="Red ">*</font> indicates required field.]]>

      </mx:htmlText>

</mx:Label>

…but the color still didn’t work.  Turns out you have to use Hex to specify font color:

<mx:Label>

      <mx:htmlText>

            <![CDATA[ <font color="#FF0000">*</font> indicates required field.]]>

      </mx:htmlText>

</mx:Label>

The Adobe LiveDocs explain all this in more detail.