From: <fab...@us...> - 2009-02-07 04:24:32
|
Revision: 4063 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4063&view=rev Author: fabiomaulo Date: 2009-02-07 04:24:29 +0000 (Sat, 07 Feb 2009) Log Message: ----------- - Fix NH-1176 - Fix NH-1664 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs trunk/nhibernate/src/NHibernate/Id/IdentifierGeneratorFactory.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Id/TriggerIdentityGenerator.cs trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/ trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/GeneratedIdentityFixture.cs trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/MyEntity.cs trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/MyEntity.hbm.xml trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.cs trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.hbm.xml trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/SimpleIdentityGeneratedFixture.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2009-02-06 20:28:16 UTC (rev 4062) +++ trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2009-02-07 04:24:29 UTC (rev 4063) @@ -2069,6 +2069,32 @@ return insertString; } + /// <summary> + /// The class (which implements <see cref="NHibernate.Id.IIdentifierGenerator"/>) + /// which acts as this dialects identity-style generation strategy. + /// </summary> + /// <returns> The native generator class. </returns> + /// <remarks> + /// Comes into play whenever the user specifies the "identity" generator. + /// </remarks> + public virtual System.Type IdentityStyleIdentifierGeneratorClass + { + get + { + if (SupportsIdentityColumns) + { + return typeof(IdentityGenerator); + } + else if (SupportsSequences) + { + return typeof(SequenceIdentityGenerator); + } + else + { + return typeof(TriggerIdentityGenerator); + } + } + } #endregion } } Modified: trunk/nhibernate/src/NHibernate/Id/IdentifierGeneratorFactory.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Id/IdentifierGeneratorFactory.cs 2009-02-06 20:28:16 UTC (rev 4062) +++ trunk/nhibernate/src/NHibernate/Id/IdentifierGeneratorFactory.cs 2009-02-07 04:24:29 UTC (rev 4063) @@ -79,7 +79,7 @@ /// </remarks> public sealed class IdentifierGeneratorFactory { - private static readonly ILog log = LogManager.GetLogger(typeof(IdentifierGeneratorFactory)); + private static readonly ILog log = LogManager.GetLogger(typeof (IdentifierGeneratorFactory)); /// <summary> Get the generated identifier when using identity columns</summary> /// <param name="rs">The <see cref="IDataReader"/> to read the identifier value from.</param> @@ -101,7 +101,6 @@ return id; } - /// <summary> /// Gets the value of the identifier from the <see cref="IDataReader"/> and /// ensures it is the correct <see cref="System.Type"/>. @@ -142,7 +141,7 @@ /// has already been saved. /// </summary> /// <value> - /// <see cref="String.Empty">String.Empty</see> + /// <see cref="string.Empty">String.Empty</see> /// </value> public static readonly object ShortCircuitIndicator = new object(); @@ -156,22 +155,22 @@ /// </summary> static IdentifierGeneratorFactory() { - idgenerators.Add("uuid.hex", typeof(UUIDHexGenerator)); - idgenerators.Add("uuid.string", typeof(UUIDStringGenerator)); - idgenerators.Add("hilo", typeof(TableHiLoGenerator)); - idgenerators.Add("assigned", typeof(Assigned)); - idgenerators.Add("counter", typeof(CounterGenerator)); - idgenerators.Add("identity", typeof(IdentityGenerator)); - idgenerators.Add("increment", typeof(IncrementGenerator)); - idgenerators.Add("sequence", typeof(SequenceGenerator)); - idgenerators.Add("seqhilo", typeof(SequenceHiLoGenerator)); - idgenerators.Add("vm", typeof(CounterGenerator)); - idgenerators.Add("foreign", typeof(ForeignGenerator)); - idgenerators.Add("guid", typeof(GuidGenerator)); - idgenerators.Add("guid.comb", typeof(GuidCombGenerator)); - idgenerators.Add("guid.native", typeof(NativeGuidGenerator)); - idgenerators.Add("select", typeof(SelectGenerator)); - idgenerators.Add("sequence-identity", typeof(SequenceIdentityGenerator)); + idgenerators.Add("uuid.hex", typeof (UUIDHexGenerator)); + idgenerators.Add("uuid.string", typeof (UUIDStringGenerator)); + idgenerators.Add("hilo", typeof (TableHiLoGenerator)); + idgenerators.Add("assigned", typeof (Assigned)); + idgenerators.Add("counter", typeof (CounterGenerator)); + idgenerators.Add("increment", typeof (IncrementGenerator)); + idgenerators.Add("sequence", typeof (SequenceGenerator)); + idgenerators.Add("seqhilo", typeof (SequenceHiLoGenerator)); + idgenerators.Add("vm", typeof (CounterGenerator)); + idgenerators.Add("foreign", typeof (ForeignGenerator)); + idgenerators.Add("guid", typeof (GuidGenerator)); + idgenerators.Add("guid.comb", typeof (GuidCombGenerator)); + idgenerators.Add("guid.native", typeof (NativeGuidGenerator)); + idgenerators.Add("select", typeof (SelectGenerator)); + idgenerators.Add("sequence-identity", typeof (SequenceIdentityGenerator)); + idgenerators.Add("trigger-identity", typeof (TriggerIdentityGenerator)); } private IdentifierGeneratorFactory() @@ -196,15 +195,18 @@ /// <exception cref="MappingException"> /// Thrown if there are any exceptions while creating the <see cref="IIdentifierGenerator"/>. /// </exception> - public static IIdentifierGenerator Create(string strategy, IType type, IDictionary<string, string> parms, Dialect.Dialect dialect) + public static IIdentifierGenerator Create(string strategy, IType type, IDictionary<string, string> parms, + Dialect.Dialect dialect) { try { System.Type clazz = GetIdentifierGeneratorClass(strategy, dialect); - IIdentifierGenerator idgen = (IIdentifierGenerator)Activator.CreateInstance(clazz); - IConfigurable conf = idgen as IConfigurable; + var idgen = (IIdentifierGenerator) Activator.CreateInstance(clazz); + var conf = idgen as IConfigurable; if (conf != null) + { conf.Configure(type, parms, dialect); + } return idgen; } catch (IdentifierGenerationException) @@ -226,47 +228,47 @@ /// The identifier value converted to the <see cref="System.Type"/>. /// </returns> /// <exception cref="IdentifierGenerationException"> - /// The <c>type</c> parameter must be an <see cref="Int16"/>, <see cref="Int32"/>, - /// or <see cref="Int64"/>. + /// The <c>type</c> parameter must be an <see cref="short"/>, <see cref="int"/>, + /// or <see cref="long"/>. /// </exception> public static object CreateNumber(long value, System.Type type) { // Convert.ChangeType would be better here, but it fails if the value does not fit // in the destination type, while we need the value to be truncated in this case. - if (type == typeof(byte)) + if (type == typeof (byte)) { return (byte) value; } - else if (type == typeof(sbyte)) + else if (type == typeof (sbyte)) { return (sbyte) value; } - else if (type == typeof(short)) + else if (type == typeof (short)) { return (short) value; } - else if (type == typeof(ushort)) + else if (type == typeof (ushort)) { return (ushort) value; } - else if (type == typeof(int)) + else if (type == typeof (int)) { return (int) value; } - else if (type == typeof(uint)) + else if (type == typeof (uint)) { return (uint) value; } - else if (type == typeof(long)) + else if (type == typeof (long)) { return value; } - else if (type == typeof(ulong)) + else if (type == typeof (ulong)) { return (ulong) value; } - else if (type == typeof(decimal)) + else if (type == typeof (decimal)) { return (decimal) value; } @@ -286,13 +288,24 @@ public static System.Type GetIdentifierGeneratorClass(string strategy, Dialect.Dialect dialect) { System.Type clazz; - idgenerators.TryGetValue(strategy, out clazz); if ("native".Equals(strategy)) + { clazz = dialect.NativeIdentifierGeneratorClass; + } + else if ("identity".Equals(strategy)) + { + clazz = dialect.IdentityStyleIdentifierGeneratorClass; + } + else + { + idgenerators.TryGetValue(strategy, out clazz); + } try { if (clazz == null) + { clazz = ReflectHelper.ClassForName(strategy); + } } catch (Exception) { Added: trunk/nhibernate/src/NHibernate/Id/TriggerIdentityGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Id/TriggerIdentityGenerator.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Id/TriggerIdentityGenerator.cs 2009-02-07 04:24:29 UTC (rev 4063) @@ -0,0 +1,18 @@ +using NHibernate.Engine; +using NHibernate.Id.Insert; + +namespace NHibernate.Id +{ + public class TriggerIdentityGenerator : AbstractPostInsertGenerator + { + #region Overrides of AbstractPostInsertGenerator + + public override IInsertGeneratedIdentifierDelegate GetInsertGeneratedIdentifierDelegate( + IPostInsertIdentityPersister persister, ISessionFactoryImplementor factory, bool isGetGeneratedKeysEnabled) + { + return new OutputParamReturningDelegate(persister, factory); + } + + #endregion + } +} \ No newline at end of file Property changes on: trunk/nhibernate/src/NHibernate/Id/TriggerIdentityGenerator.cs ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-02-06 20:28:16 UTC (rev 4062) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-02-07 04:24:29 UTC (rev 4063) @@ -464,6 +464,7 @@ <Compile Include="Exceptions\ReflectionBasedSqlStateExtracter.cs" /> <Compile Include="Exceptions\SqlStateExtracter.cs" /> <Compile Include="Exceptions\TemplatedViolatedConstraintNameExtracter.cs" /> + <Compile Include="Id\TriggerIdentityGenerator.cs" /> <Compile Include="Id\Insert\NoCommentsInsert.cs" /> <Compile Include="Id\Insert\ReturningIdentifierInsert.cs" /> <Compile Include="Id\Insert\OutputParamReturningDelegate.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/GeneratedIdentityFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/GeneratedIdentityFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/GeneratedIdentityFixture.cs 2009-02-07 04:24:29 UTC (rev 4063) @@ -0,0 +1,41 @@ +using System.Collections; +using NUnit.Framework; + +namespace NHibernate.Test.Generatedkeys.ByTrigger +{ + [TestFixture] + public class GeneratedIdentityFixture : TestCase + { + protected override IList Mappings + { + get { return new[] { "Generatedkeys.ByTrigger.MyEntity.hbm.xml" }; } + } + + protected override string MappingsAssembly + { + get { return "NHibernate.Test"; } + } + + protected override bool AppliesTo(Dialect.Dialect dialect) + { + return dialect is Dialect.Oracle8iDialect; + } + + [Test] + public void GetGeneratedKeysSupport() + { + ISession session = OpenSession(); + session.BeginTransaction(); + + var e = new MyEntity { Name = "entity-1" }; + session.Save(e); + + // this insert should happen immediately! + Assert.AreEqual(1, e.Id, "id not generated through forced insertion"); + + session.Delete(e); + session.Transaction.Commit(); + session.Close(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/MyEntity.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/MyEntity.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/MyEntity.cs 2009-02-07 04:24:29 UTC (rev 4063) @@ -0,0 +1,9 @@ +namespace NHibernate.Test.Generatedkeys.ByTrigger +{ + public class MyEntity + { + public virtual int Id { get; private set; } + + public virtual string Name { get; set; } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/MyEntity.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/MyEntity.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Generatedkeys/ByTrigger/MyEntity.hbm.xml 2009-02-07 04:24:29 UTC (rev 4063) @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.Generatedkeys.ByTrigger" + default-access="backfield"> + + <class name="MyEntity" table="my_entity"> + <id name="Id"> + <generator class="trigger-identity"/> + </id> + <property name="Name"/> + </class> + + <database-object> + <create> + <![CDATA[CREATE SEQUENCE NH_SEQ START WITH 1 CACHE 20]]> + </create> + <drop> + <![CDATA[DROP SEQUENCE NH_SEQ]]> + </drop> + <dialect-scope name="NHibernate.Dialect.Oracle8iDialect"/> + <dialect-scope name="NHibernate.Dialect.Oracle9iDialect"/> + <dialect-scope name="NHibernate.Dialect.Oracle10gDialect"/> + </database-object> + + <database-object> + <create> + <![CDATA[CREATE OR REPLACE TRIGGER T_BI_my_entity + BEFORE INSERT ON my_entity + FOR EACH ROW + BEGIN + select NH_SEQ.nextval into :new.ID from DUAL; + END;]]> + </create> + <drop> + <![CDATA[DROP TRIGGER T_BI_my_entity]]> + </drop> + <dialect-scope name="NHibernate.Dialect.Oracle8iDialect"/> + <dialect-scope name="NHibernate.Dialect.Oracle9iDialect"/> + <dialect-scope name="NHibernate.Dialect.Oracle10gDialect"/> + </database-object> + + +</hibernate-mapping> \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.cs 2009-02-07 04:24:29 UTC (rev 4063) @@ -0,0 +1,19 @@ +namespace NHibernate.Test.Generatedkeys.Identity +{ + public class MyEntityIdentity + { + private int id; + private string name; + + public virtual int Id + { + get { return id; } + } + + public virtual string Name + { + get { return name; } + set { name = value; } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.hbm.xml 2009-02-07 04:24:29 UTC (rev 4063) @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.Generatedkeys.Identity" + default-access="field"> + + <class name="MyEntityIdentity" table="my_entity"> + <id name="id"> + <generator class="identity"/> + </id> + <natural-id> + <property name="name"/> + </natural-id> + </class> + +</hibernate-mapping> \ No newline at end of file Property changes on: trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/MyEntityIdentity.hbm.xml ___________________________________________________________________ Added: svn:mergeinfo + Added: trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/SimpleIdentityGeneratedFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/SimpleIdentityGeneratedFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Generatedkeys/Identity/SimpleIdentityGeneratedFixture.cs 2009-02-07 04:24:29 UTC (rev 4063) @@ -0,0 +1,39 @@ +using System.Collections; +using NUnit.Framework; + +namespace NHibernate.Test.Generatedkeys.Identity +{ + [TestFixture] + public class SimpleIdentityGeneratedFixture : TestCase + { + // This test is to check the support of identity generator + // NH should choose one of the identity-style generation where the Dialect are supporting one of them + // as identity, sequence-identity (identity.sequence), generated (identity.sequence) + protected override IList Mappings + { + get { return new[] { "Generatedkeys.Identity.MyEntityIdentity.hbm.xml" }; } + } + + protected override string MappingsAssembly + { + get { return "NHibernate.Test"; } + } + + [Test] + public void SequenceIdentityGenerator() + { + ISession session = OpenSession(); + session.BeginTransaction(); + + var e = new MyEntityIdentity { Name = "entity-1" }; + session.Save(e); + + // this insert should happen immediately! + Assert.AreEqual(1, e.Id, "id not generated through forced insertion"); + + session.Delete(e); + session.Transaction.Commit(); + session.Close(); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-02-06 20:28:16 UTC (rev 4062) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-02-07 04:24:29 UTC (rev 4063) @@ -244,10 +244,14 @@ <Compile Include="FilterTest\Product.cs" /> <Compile Include="FilterTest\Salesperson.cs" /> <Compile Include="FilterTest\TestClass.cs" /> + <Compile Include="Generatedkeys\ByTrigger\GeneratedIdentityFixture.cs" /> + <Compile Include="Generatedkeys\ByTrigger\MyEntity.cs" /> <Compile Include="Generatedkeys\Identity\IdentityGeneratedKeysTest.cs" /> <Compile Include="Generatedkeys\Identity\MyChild.cs" /> <Compile Include="Generatedkeys\Identity\MyEntity.cs" /> + <Compile Include="Generatedkeys\Identity\MyEntityIdentity.cs" /> <Compile Include="Generatedkeys\Identity\MySibling.cs" /> + <Compile Include="Generatedkeys\Identity\SimpleIdentityGeneratedFixture.cs" /> <Compile Include="Generatedkeys\Select\MyEntity.cs" /> <Compile Include="Generatedkeys\Select\SelectGeneratorTest.cs" /> <Compile Include="Generatedkeys\Seqidentity\MyEntity.cs" /> @@ -1645,6 +1649,8 @@ <EmbeddedResource Include="Cascade\JobBatch.hbm.xml" /> <EmbeddedResource Include="Deletetransient\Person.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="Generatedkeys\ByTrigger\MyEntity.hbm.xml" /> + <EmbeddedResource Include="Generatedkeys\Identity\MyEntityIdentity.hbm.xml" /> <EmbeddedResource Include="SessionFactoryTest\Item.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1289\Mappings.hbm.xml" /> <EmbeddedResource Include="TypesTest\TimeSpanClass.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |