Welcome to the CodeSmith Community!

Re: Hacking nHibernate codesmith templates

Template Frameworks

A description has not yet been added to this group.

Hacking nHibernate codesmith templates

Answered (Verified) This question is answered

I'm working on a new project using CS and NH. I'm finding the NH templates are fairly entry level as far as flexibility in generating code/hbm files from sql server schemas.

Today I've added/modified them to do:

1) unit test update/delete tests work without requiring the table to have an existing record

2) Allow a cascade override for all HBM mappings. Set cs_NHCascadeOverride extended property to an arbitrary string for the FKey column. Whatever string you put there gets used as the "cascade=" value in the HBM many-to-one or bag mapping. The reason for this is for a many/many mapping like users->roles to tell hibernate not to delete a role or user if one of the other ends is deleted. A pretty fundamental requirement.

 

  • Post Points: 35
Verified Answer
  • Here's an attempt at posting a patch...

     

     

    Index: CSharp/HbmMaps/Hbm.cst
    ===================================================================
    --- CSharp/HbmMaps/Hbm.cst    (revision 728)
    +++ CSharp/HbmMaps/Hbm.cst    (working copy)
    @@ -51,7 +51,7 @@
             <% } %>
             <% // Many-To-Many %>
             <% foreach(EntityAssociation association in entityManager.ManyToMany) { %>
    -        <bag name="<%= association.PropertyName %>" table="<%= association.TableName %>" lazy="true" cascade="all" inverse="false" >
    +        <bag name="<%= association.PropertyName %>" table="<%= association.TableName %>" lazy="true" cascade="<%= association.Cascade %>" inverse="false" >
                 <key column="<%= association.ColumnName %>"></key>
                 <many-to-many column="<%= association.ToManyTableKeyName %>" class="<%= association.ClassName %>" />
             </bag>
    Index: CSharp/UnitTests/UnitTests.cst
    ===================================================================
    --- CSharp/UnitTests/UnitTests.cst    (revision 728)
    +++ CSharp/UnitTests/UnitTests.cst    (working copy)
    @@ -109,6 +109,8 @@
             {
                 try
                 {
    +                Create(); // Make sure there's a row in there
    +
                     <%= GetClassName(SourceTable) %> entityA = GetFirst<%= GetClassName(SourceTable) %>();
                    
                     <% if(entityManager.MembersNoKeyNoVersion.Count > 0) { %>
    @@ -132,6 +134,8 @@
             {
                 try
                 {
    +                Create(); // Make sure there's a row in there
    +
                     <%= GetClassName(SourceTable) %> entity = GetFirst<%= GetClassName(SourceTable) %>();
                    
                     manager.Delete(entity);
    Index: Source/NHibernateHelper/EntityAssociation.cs
    ===================================================================
    --- Source/NHibernateHelper/EntityAssociation.cs    (revision 728)
    +++ Source/NHibernateHelper/EntityAssociation.cs    (working copy)
    @@ -9,6 +9,8 @@
     {
         public class EntityAssociation : EntityBase
         {
    +        private const string CascadeOverride = "cs_nhCascadeOverride";
    +
             public EntityAssociation(AssociationTypeEnum associationType, TableSchema table, ColumnSchema column)
                 : base(column)
             {
    @@ -18,6 +20,8 @@
                 Cascade = (associationType == AssociationTypeEnum.OneToMany)
                     ? NHibernateHelper.GetCascade(column)
                     : String.Empty;
    +            if (column.ExtendedProperties.Contains(CascadeOverride))
    +                Cascade = (string) column.ExtendedProperties[CascadeOverride].Value;
                 ClassName = NHibernateHelper.GetClassName(table);
                 AssociationType = associationType;
                 GenericName = GetGenericName(table, Column, AssociationType);

  • Here's another patch. This contains the prior patch plus I added the ability to create HBM XML files with guid.comb pkeys automatically if the sql column CS_SystemType is "uniqeidentifier"

     

    Index: CSharp/HbmMaps/Hbm.cst
    ===================================================================
    --- CSharp/HbmMaps/Hbm.cst    (revision 728)
    +++ CSharp/HbmMaps/Hbm.cst    (working copy)
    @@ -25,6 +25,10 @@
                 <key-property name="<%= em.PropertyName %>" column="<%= em.ColumnName %>" />
                 <% } %>
             </composite-id>
    +        <% } else if (entityManager.PrimaryKey.KeyColumn.CSSystemType == "uniqueidentifier") { %>
    +        <id name="Id" column="<%= entityManager.PrimaryKey.KeyColumn.ColumnName %>" type="Guid">
    +            <generator class="guid.comb" />
    +        </id>
             <% } else { %>
             <id name="Id" column="<%= entityManager.PrimaryKey.KeyColumn.ColumnName %>">
                  <%= entityManager.PrimaryKey.Generator %>
    @@ -51,7 +55,7 @@
             <% } %>
             <% // Many-To-Many %>
             <% foreach(EntityAssociation association in entityManager.ManyToMany) { %>
    -        <bag name="<%= association.PropertyName %>" table="<%= association.TableName %>" lazy="true" cascade="all" inverse="false" >
    +        <bag name="<%= association.PropertyName %>" table="<%= association.TableName %>" lazy="true" cascade="<%= association.Cascade %>" inverse="false" >
                 <key column="<%= association.ColumnName %>"></key>
                 <many-to-many column="<%= association.ToManyTableKeyName %>" class="<%= association.ClassName %>" />
             </bag>
    Index: CSharp/UnitTests/UnitTests.cst
    ===================================================================
    --- CSharp/UnitTests/UnitTests.cst    (revision 728)
    +++ CSharp/UnitTests/UnitTests.cst    (working copy)
    @@ -109,6 +109,8 @@
             {
                 try
                 {
    +                Create(); // Make sure there's a row in there
    +
                     <%= GetClassName(SourceTable) %> entityA = GetFirst<%= GetClassName(SourceTable) %>();
                    
                     <% if(entityManager.MembersNoKeyNoVersion.Count > 0) { %>
    @@ -132,6 +134,8 @@
             {
                 try
                 {
    +                Create(); // Make sure there's a row in there
    +
                     <%= GetClassName(SourceTable) %> entity = GetFirst<%= GetClassName(SourceTable) %>();
                    
                     manager.Delete(entity);
    Index: Source/NHibernateHelper/EntityAssociation.cs
    ===================================================================
    --- Source/NHibernateHelper/EntityAssociation.cs    (revision 728)
    +++ Source/NHibernateHelper/EntityAssociation.cs    (working copy)
    @@ -9,6 +9,8 @@
     {
         public class EntityAssociation : EntityBase
         {
    +        private const string CascadeOverride = "cs_nhCascadeOverride";
    +
             public EntityAssociation(AssociationTypeEnum associationType, TableSchema table, ColumnSchema column)
                 : base(column)
             {
    @@ -18,6 +20,8 @@
                 Cascade = (associationType == AssociationTypeEnum.OneToMany)
                     ? NHibernateHelper.GetCascade(column)
                     : String.Empty;
    +            if (column.ExtendedProperties.Contains(CascadeOverride))
    +                Cascade = (string) column.ExtendedProperties[CascadeOverride].Value;
                 ClassName = NHibernateHelper.GetClassName(table);
                 AssociationType = associationType;
                 GenericName = GetGenericName(table, Column, AssociationType);
    Index: Source/NHibernateHelper/EntityBase.cs
    ===================================================================
    --- Source/NHibernateHelper/EntityBase.cs    (revision 728)
    +++ Source/NHibernateHelper/EntityBase.cs    (working copy)
    @@ -9,11 +9,17 @@
     {
         public abstract class EntityBase
         {
    +        const string cs_SystemType = "CS_SystemType";
             private string _genericName;
     
             public EntityBase(ColumnSchema column)
             {
                 Column = column;
    +            CSSystemType = "";
    +            if (column.ExtendedProperties.Contains(cs_SystemType))
    +            {
    +                CSSystemType = column.ExtendedProperties[cs_SystemType].Value.ToString();
    +            }
             }
     
             private static string GetPropertyName(string name)
    @@ -71,5 +77,7 @@
             {
                 get { return Column.IsPrimaryKeyMember; }
             }
    +
    +        public string CSSystemType { get; set; }
         }
     }

All Replies
  • Hello,

    Would you mind sending us your template changes?

    Thanks
    -Blake Niemyjski

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

  • yeah when I get a chance. Also I'm sure I'll be adding more extended properties for NH mapping overrides.

    I can post a patch here if the max post length isn't too small

  • Hello,

    That shouldn't be the case. If it doesn't work can you send it into support?

    Thanks
    -Blake Niemyjski

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

  • Here's an attempt at posting a patch...

     

     

    Index: CSharp/HbmMaps/Hbm.cst
    ===================================================================
    --- CSharp/HbmMaps/Hbm.cst    (revision 728)
    +++ CSharp/HbmMaps/Hbm.cst    (working copy)
    @@ -51,7 +51,7 @@
             <% } %>
             <% // Many-To-Many %>
             <% foreach(EntityAssociation association in entityManager.ManyToMany) { %>
    -        <bag name="<%= association.PropertyName %>" table="<%= association.TableName %>" lazy="true" cascade="all" inverse="false" >
    +        <bag name="<%= association.PropertyName %>" table="<%= association.TableName %>" lazy="true" cascade="<%= association.Cascade %>" inverse="false" >
                 <key column="<%= association.ColumnName %>"></key>
                 <many-to-many column="<%= association.ToManyTableKeyName %>" class="<%= association.ClassName %>" />
             </bag>
    Index: CSharp/UnitTests/UnitTests.cst
    ===================================================================
    --- CSharp/UnitTests/UnitTests.cst    (revision 728)
    +++ CSharp/UnitTests/UnitTests.cst    (working copy)
    @@ -109,6 +109,8 @@
             {
                 try
                 {
    +                Create(); // Make sure there's a row in there
    +
                     <%= GetClassName(SourceTable) %> entityA = GetFirst<%= GetClassName(SourceTable) %>();
                    
                     <% if(entityManager.MembersNoKeyNoVersion.Count > 0) { %>
    @@ -132,6 +134,8 @@
             {
                 try
                 {
    +                Create(); // Make sure there's a row in there
    +
                     <%= GetClassName(SourceTable) %> entity = GetFirst<%= GetClassName(SourceTable) %>();
                    
                     manager.Delete(entity);
    Index: Source/NHibernateHelper/EntityAssociation.cs
    ===================================================================
    --- Source/NHibernateHelper/EntityAssociation.cs    (revision 728)
    +++ Source/NHibernateHelper/EntityAssociation.cs    (working copy)
    @@ -9,6 +9,8 @@
     {
         public class EntityAssociation : EntityBase
         {
    +        private const string CascadeOverride = "cs_nhCascadeOverride";
    +
             public EntityAssociation(AssociationTypeEnum associationType, TableSchema table, ColumnSchema column)
                 : base(column)
             {
    @@ -18,6 +20,8 @@
                 Cascade = (associationType == AssociationTypeEnum.OneToMany)
                     ? NHibernateHelper.GetCascade(column)
                     : String.Empty;
    +            if (column.ExtendedProperties.Contains(CascadeOverride))
    +                Cascade = (string) column.ExtendedProperties[CascadeOverride].Value;
                 ClassName = NHibernateHelper.GetClassName(table);
                 AssociationType = associationType;
                 GenericName = GetGenericName(table, Column, AssociationType);

  • Here's another patch. This contains the prior patch plus I added the ability to create HBM XML files with guid.comb pkeys automatically if the sql column CS_SystemType is "uniqeidentifier"

     

    Index: CSharp/HbmMaps/Hbm.cst
    ===================================================================
    --- CSharp/HbmMaps/Hbm.cst    (revision 728)
    +++ CSharp/HbmMaps/Hbm.cst    (working copy)
    @@ -25,6 +25,10 @@
                 <key-property name="<%= em.PropertyName %>" column="<%= em.ColumnName %>" />
                 <% } %>
             </composite-id>
    +        <% } else if (entityManager.PrimaryKey.KeyColumn.CSSystemType == "uniqueidentifier") { %>
    +        <id name="Id" column="<%= entityManager.PrimaryKey.KeyColumn.ColumnName %>" type="Guid">
    +            <generator class="guid.comb" />
    +        </id>
             <% } else { %>
             <id name="Id" column="<%= entityManager.PrimaryKey.KeyColumn.ColumnName %>">
                  <%= entityManager.PrimaryKey.Generator %>
    @@ -51,7 +55,7 @@
             <% } %>
             <% // Many-To-Many %>
             <% foreach(EntityAssociation association in entityManager.ManyToMany) { %>
    -        <bag name="<%= association.PropertyName %>" table="<%= association.TableName %>" lazy="true" cascade="all" inverse="false" >
    +        <bag name="<%= association.PropertyName %>" table="<%= association.TableName %>" lazy="true" cascade="<%= association.Cascade %>" inverse="false" >
                 <key column="<%= association.ColumnName %>"></key>
                 <many-to-many column="<%= association.ToManyTableKeyName %>" class="<%= association.ClassName %>" />
             </bag>
    Index: CSharp/UnitTests/UnitTests.cst
    ===================================================================
    --- CSharp/UnitTests/UnitTests.cst    (revision 728)
    +++ CSharp/UnitTests/UnitTests.cst    (working copy)
    @@ -109,6 +109,8 @@
             {
                 try
                 {
    +                Create(); // Make sure there's a row in there
    +
                     <%= GetClassName(SourceTable) %> entityA = GetFirst<%= GetClassName(SourceTable) %>();
                    
                     <% if(entityManager.MembersNoKeyNoVersion.Count > 0) { %>
    @@ -132,6 +134,8 @@
             {
                 try
                 {
    +                Create(); // Make sure there's a row in there
    +
                     <%= GetClassName(SourceTable) %> entity = GetFirst<%= GetClassName(SourceTable) %>();
                    
                     manager.Delete(entity);
    Index: Source/NHibernateHelper/EntityAssociation.cs
    ===================================================================
    --- Source/NHibernateHelper/EntityAssociation.cs    (revision 728)
    +++ Source/NHibernateHelper/EntityAssociation.cs    (working copy)
    @@ -9,6 +9,8 @@
     {
         public class EntityAssociation : EntityBase
         {
    +        private const string CascadeOverride = "cs_nhCascadeOverride";
    +
             public EntityAssociation(AssociationTypeEnum associationType, TableSchema table, ColumnSchema column)
                 : base(column)
             {
    @@ -18,6 +20,8 @@
                 Cascade = (associationType == AssociationTypeEnum.OneToMany)
                     ? NHibernateHelper.GetCascade(column)
                     : String.Empty;
    +            if (column.ExtendedProperties.Contains(CascadeOverride))
    +                Cascade = (string) column.ExtendedProperties[CascadeOverride].Value;
                 ClassName = NHibernateHelper.GetClassName(table);
                 AssociationType = associationType;
                 GenericName = GetGenericName(table, Column, AssociationType);
    Index: Source/NHibernateHelper/EntityBase.cs
    ===================================================================
    --- Source/NHibernateHelper/EntityBase.cs    (revision 728)
    +++ Source/NHibernateHelper/EntityBase.cs    (working copy)
    @@ -9,11 +9,17 @@
     {
         public abstract class EntityBase
         {
    +        const string cs_SystemType = "CS_SystemType";
             private string _genericName;
     
             public EntityBase(ColumnSchema column)
             {
                 Column = column;
    +            CSSystemType = "";
    +            if (column.ExtendedProperties.Contains(cs_SystemType))
    +            {
    +                CSSystemType = column.ExtendedProperties[cs_SystemType].Value.ToString();
    +            }
             }
     
             private static string GetPropertyName(string name)
    @@ -71,5 +77,7 @@
             {
                 get { return Column.IsPrimaryKeyMember; }
             }
    +
    +        public string CSSystemType { get; set; }
         }
     }

  • Hello,

    Thanks, I'll pass this on.

    Thanks
    -Blake Niemyjski

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

Page 1 of 1 (7 items)