Skip to content

Commit

Permalink
NH-1316 - Fix returing generated identity for PostgreSQL
Browse files Browse the repository at this point in the history
Fixes #1201
  • Loading branch information
hazzik committed Jun 13, 2018
1 parent 1024b71 commit 06ad6ac
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
using NHibernate.Dialect;


namespace NHibernate.Test.NHSpecificTest.NH2204
namespace NHibernate.Test.NHSpecificTest.NH1316
{
using System.Threading.Tasks;
[TestFixture]
Expand Down Expand Up @@ -66,7 +66,7 @@ protected override void OnTearDown()


[Test]
public async Task KnownFailure_Correct_Id_Returned_When_Using_TriggerAsync()
public async Task Correct_Id_Returned_When_Using_TriggerAsync()
{
//We expected this test to fail - if the problem has been fixed, clean-up the test.
var entity1 = new Parent {Name = "Parent1_0"}; // when saved this entity should have the id of 1
Expand Down Expand Up @@ -100,13 +100,10 @@ public async Task KnownFailure_Correct_Id_Returned_When_Using_TriggerAsync()
await (s.SaveAsync(entity3));
await (s.FlushAsync());

Warn.Unless(
Assert.That(
entity3.Id,
Is.EqualTo(3),
"oh uh - it would appear that lastval() is not our friend when a trigger updates other sequences.");

// now would be a good time to look at the data in the tables and see that they have the IDs as expected
// which are not the same as those returned by nhibernate
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using System;
using System.Data.Common;
using NUnit.Framework;
using NHibernate.Dialect;
using NUnit.Framework;


namespace NHibernate.Test.NHSpecificTest.NH2204
namespace NHibernate.Test.NHSpecificTest.NH1316
{
[TestFixture]
public class Fixture : BugTestCase
Expand Down Expand Up @@ -55,7 +53,7 @@ protected override void OnTearDown()


[Test]
public void KnownFailure_Correct_Id_Returned_When_Using_Trigger()
public void Correct_Id_Returned_When_Using_Trigger()
{
//We expected this test to fail - if the problem has been fixed, clean-up the test.
var entity1 = new Parent {Name = "Parent1_0"}; // when saved this entity should have the id of 1
Expand Down Expand Up @@ -89,13 +87,10 @@ public void KnownFailure_Correct_Id_Returned_When_Using_Trigger()
s.Save(entity3);
s.Flush();

Warn.Unless(
Assert.That(
entity3.Id,
Is.EqualTo(3),
"oh uh - it would appear that lastval() is not our friend when a trigger updates other sequences.");

// now would be a good time to look at the data in the tables and see that they have the IDs as expected
// which are not the same as those returned by nhibernate
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/NH1316/Mappings.hbm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHibernate.Test"
namespace="NHibernate.Test.NHSpecificTest.NH1316">

<class name="Parent">
<id name="Id">
<generator class="native" />

</id>
<property name="Name" />

</class>


<class name="ParentHistory" table="parent_history">
<id name="HistId">
<generator class="native" />
</id>

<property name="HistWhen" />
<property name="Id" />
<property name="Name" />
</class>

</hibernate-mapping>
19 changes: 19 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/NH1316/Model.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace NHibernate.Test.NHSpecificTest.NH1316
{
public class Parent
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}

public class ParentHistory
{
public virtual int HistId { get; set; }
public virtual DateTime HistWhen { get; set; }

public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
}
1 change: 0 additions & 1 deletion src/NHibernate.Test/NHSpecificTest/NH2204/Mappings.hbm.xml

This file was deleted.

1 change: 0 additions & 1 deletion src/NHibernate.Test/NHSpecificTest/NH2204/Model.cs

This file was deleted.

18 changes: 17 additions & 1 deletion src/NHibernate/Dialect/Dialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ public virtual bool HasDataTypeInIdentityColumn
}

/// <summary>
/// Provided we <see cref="SupportsInsertSelectIdentity"/>, then attch the
/// Provided we <see cref="SupportsInsertSelectIdentity"/>, then attach the
/// "select identity" clause to the insert statement.
/// </summary>
/// <param name="insertString">The insert command </param>
Expand All @@ -990,6 +990,22 @@ public virtual SqlString AppendIdentitySelectToInsert(SqlString insertString)
return insertString;
}

/// <summary>
/// Provided we <see cref="SupportsInsertSelectIdentity"/>, then attach the
/// "select identity" clause to the insert statement.
/// </summary>
/// <param name="insertString">The insert command </param>
/// <param name="identifierColumnName">The identifier name</param>
/// <returns>
/// The insert command with any necessary identity select clause attached.
/// Note, if <see cref="SupportsInsertSelectIdentity"/> == false then
/// the insert-string should be returned without modification.
/// </returns>
public virtual SqlString AppendIdentitySelectToInsert(SqlString insertString, string identifierColumnName)
{
return AppendIdentitySelectToInsert(insertString);
}

/// <summary>
/// Get the select command to use to retrieve the last generated IDENTITY
/// value for a particular table.
Expand Down
5 changes: 5 additions & 0 deletions src/NHibernate/Dialect/PostgreSQL81Dialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ public override SqlString AppendIdentitySelectToInsert(SqlString insertSql)
return insertSql.Append("; " + IdentitySelectString);
}

public override SqlString AppendIdentitySelectToInsert(SqlString insertString, string identifierColumnName)
{
return insertString.Append(" returning ").Append(identifierColumnName);
}

public override bool SupportsInsertSelectIdentity
{
get { return true; }
Expand Down
2 changes: 1 addition & 1 deletion src/NHibernate/Dialect/PostgreSQLDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public override string GetDropSequenceString(string sequenceName)

public override SqlString AddIdentifierOutParameterToInsert(SqlString insertString, string identifierColumnName, string parameterName)
{
return insertString.Append(" returning " + identifierColumnName);
return insertString.Append(" returning ").Append(identifierColumnName);
}

public override InsertGeneratedIdentifierRetrievalMethod InsertGeneratedIdentifierRetrievalMethod
Expand Down
2 changes: 1 addition & 1 deletion src/NHibernate/Id/IdentityGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public InsertSelectDelegate(IPostInsertIdentityPersister persister, ISessionFact

public override IdentifierGeneratingInsert PrepareIdentifierGeneratingInsert()
{
InsertSelectIdentityInsert insert = new InsertSelectIdentityInsert(factory);
var insert = new InsertSelectIdentityInsert(factory, persister.RootTableKeyColumnNames[0]);
insert.AddIdentityColumn(persister.RootTableKeyColumnNames[0]);
return insert;
}
Expand Down
13 changes: 12 additions & 1 deletion src/NHibernate/Id/Insert/InsertSelectIdentityInsert.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using NHibernate.Engine;
using NHibernate.SqlCommand;

Expand All @@ -10,14 +11,24 @@ namespace NHibernate.Id.Insert
/// </summary>
public class InsertSelectIdentityInsert : IdentifierGeneratingInsert
{
private readonly string _identifierColumnName;

//Since v5.2
[Obsolete("Please use constructor accepting identifierColumnName parameter.")]
public InsertSelectIdentityInsert(ISessionFactoryImplementor factory)
: base(factory)
{
}

public InsertSelectIdentityInsert(ISessionFactoryImplementor factory, string identifierColumnName)
: base(factory)
{
_identifierColumnName = identifierColumnName;
}

public override SqlString ToSqlString()
{
return Dialect.AppendIdentitySelectToInsert(base.ToSqlString());
return Dialect.AppendIdentitySelectToInsert(base.ToSqlString(), _identifierColumnName);
}
}
}
4 changes: 2 additions & 2 deletions src/NHibernate/Id/Insert/ReturningIdentifierInsert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public class ReturningIdentifierInsert : NoCommentsInsert
private readonly string identifierColumnName;
private readonly string returnParameterName;

public ReturningIdentifierInsert(ISessionFactoryImplementor factory, string identifierColumnName,
string returnParameterName) : base(factory)
public ReturningIdentifierInsert(ISessionFactoryImplementor factory, string identifierColumnName, string returnParameterName)
: base(factory)
{
this.returnParameterName = returnParameterName;
this.identifierColumnName = identifierColumnName;
Expand Down

0 comments on commit 06ad6ac

Please sign in to comment.