public virtual void UpdateProperty()
		{
			ClearCounts();
	
			Contract c = new Contract(null, "gail", "phone");
			c.AddParty(new Party("party"));
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(c);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
			c.CustomerName = "yogi";
			Assert.That(c.Parties.Count, Is.EqualTo(1));
			Party party = c.Parties.First();
			party.Name = "new party";
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
			Assert.That(c.Parties.Count, Is.EqualTo(1));
			party = c.Parties.First();
			Assert.That(party.Name, Is.EqualTo("party"));
			if (isContractPartiesBidirectional)
			{
				Assert.That(party.Contract, Is.SameAs(c));
			}
			s.Delete(c);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Party>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(2);
		}
		public void ManyToManyCollectionOptimisticLockingWithUpdate()
		{
			ClearCounts();
	
			Plan pOrig = new Plan("plan");
			Contract cOrig = new Contract(null, "gail", "phone");
			pOrig.AddContract(cOrig);
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(pOrig);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			Plan p = s.Get<Plan>(pOrig.Id);
			Contract newC = new Contract(null, "yogi", "pawprint");
			p.AddContract(newC);
			t.Commit();
			s.Close();
	
			AssertInsertCount(1);
			AssertUpdateCount(isContractVersioned ? 1 : 0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			pOrig.RemoveContract(cOrig);
			s.Update(pOrig);
			try
			{
				t.Commit();
				Assert.That(isContractVersioned, Is.False);
			}
			catch (StaleObjectStateException ex)
			{
				Assert.That(isContractVersioned, Is.True);
				t.Rollback();
			}
			s.Close();
	
			s = OpenSession();
			t = s.BeginTransaction();
			p = s.CreateCriteria<Plan>().UniqueResult<Plan>();
			s.Delete(p);
			s.CreateQuery("delete from Contract").ExecuteUpdate();
			Assert.That(s.CreateCriteria<Plan>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
		}
		public void RemoveManyToManyElementByDelete()
		{
			ClearCounts();
	
			Plan p = new Plan("plan");
			Contract c = new Contract(null, "gail", "phone");
			p.AddContract(c);
	
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(p);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			p.RemoveContract(c);
			Assert.That(p.Contracts.Count, Is.EqualTo(0));
			if (isPlanContractsBidirectional)
			{
				Assert.That(c.Plans.Count, Is.EqualTo(0));
			}
	
			s = OpenSession();
			t = s.BeginTransaction();
			s.Update(p);
			s.Delete(c);
			t.Commit();
			s.Close();
	
			AssertUpdateCount(isPlanVersioned ? 1 : 0);
			AssertDeleteCount(1);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			p = s.CreateCriteria<Plan>().UniqueResult<Plan>();
			Assert.That(p.Contracts.Count, Is.EqualTo(0));
			s.Delete(p);
			Assert.That(s.CreateCriteria<Plan>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(1);
		}
		public void CreateWithNonEmptyManyToManyCollectionMergeWithNewElement()
		{
			ClearCounts();
	
			Plan p = new Plan("plan");
			Contract c = new Contract(null, "gail", "phone");
			p.AddContract(c);
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(p);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			Contract newC = new Contract(null, "yogi", "mail");
			p.AddContract(newC);
	
			s = OpenSession();
			t = s.BeginTransaction();
			p = (Plan)s.Merge(p);
			t.Commit();
			s.Close();
	
			AssertInsertCount(1);
			AssertUpdateCount(isContractVersioned && isPlanVersioned ? 1 : 0);  // NH-specific: Hibernate issues a seperate UPDATE for the version number
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			p = s.CreateCriteria<Plan>().UniqueResult<Plan>();
			Assert.That(p.Contracts.Count, Is.EqualTo(2));
			foreach (Contract aContract in p.Contracts)
			{
				if (aContract.Id == c.Id)
				{
					Assert.That(aContract.CustomerName, Is.EqualTo("gail"));
				}
				else if (!aContract.CustomerName.Equals(newC.CustomerName))
				{
					Assert.Fail("unknown contract:" + aContract.CustomerName);
				}
				if (isPlanContractsBidirectional)
				{
					Assert.That(aContract.Plans.First(), Is.SameAs(p));
				}
			}
			s.Delete(p);
			Assert.That(s.CreateCriteria<Plan>().SetProjection(Projections.RowCountInt64()).UniqueResult(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(3);
		}
		public void CreateWithEmptyManyToManyCollectionMergeWithExistingElement()
		{
			ClearCounts();
	
			Plan p = new Plan("plan");
			Contract c = new Contract(null, "gail", "phone");
	
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(p);
			s.Persist(c);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			p.AddContract(c);
	
			s = OpenSession();
			t = s.BeginTransaction();
			p = (Plan)s.Merge(p);
			t.Commit();
			s.Close();
	
			AssertInsertCount(0);
			AssertUpdateCount(isContractVersioned && isPlanVersioned ? 2 : 0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			p = s.CreateCriteria<Plan>().UniqueResult<Plan>();
			Assert.That(p.Contracts.Count, Is.EqualTo(1));
			c = p.Contracts.First();
			Assert.That(c.CustomerName, Is.EqualTo("gail"));
			if (isPlanContractsBidirectional)
			{
				Assert.That(c.Plans.First(), Is.SameAs(p));
			}
			s.Delete(p);
			Assert.That(s.CreateCriteria<Plan>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(2);
		}
		public void CreateWithNonEmptyManyToManyCollectionUpdateWithNewElement()
		{
			ClearCounts();
	
			Plan p = new Plan("plan");
			Contract c = new Contract(null, "gail", "phone");
			p.AddContract(c);
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(p);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			Contract newC = new Contract(null, "sherman", "telepathy");
			p.AddContract(newC);
	
			s = OpenSession();
			t = s.BeginTransaction();
			s.Update(p);
			t.Commit();
			s.Close();
	
			AssertInsertCount(1);
			AssertUpdateCount(isContractVersioned ? 1 : 0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			p = s.CreateCriteria<Plan>().UniqueResult<Plan>();
			Assert.That(p.Contracts.Count, Is.EqualTo(2));
			foreach (Contract aContract in p.Contracts)
			{
				if (aContract.Id == c.Id)
				{
					Assert.That(aContract.CustomerName, Is.EqualTo("gail"));
				}
				else if (aContract.Id == newC.Id)
				{
					Assert.That(aContract.CustomerName, Is.EqualTo("sherman"));
				}
				else
				{
					Assert.Fail("unknown contract");
				}
				if (isPlanContractsBidirectional)
				{
					Assert.That(aContract.Plans.First(), Is.SameAs(p));
				}
			}
			s.Delete(p);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Plan>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(3);
		}
		public virtual void RemoveOneToManyOrphanUsingUpdate()
		{
			ClearCounts();
	
			Contract c = new Contract(null, "gail", "phone");
			ContractVariation cv = new ContractVariation(c);
			cv.Text = "cv1";
	
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(c);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			c.Variations.Remove(cv);
			cv.Contract = null;
			Assert.That(c.Variations.Count, Is.EqualTo(0));
			
			if (isContractVariationsBidirectional)
			{
				Assert.That(cv.Contract, Is.Null);
			}
	
			s = OpenSession();
			t = s.BeginTransaction();
			s.Update(c);
			t.Commit();
			s.Close();
	
			AssertUpdateCount(isContractVersioned ? 1 : 0);
			AssertDeleteCount(1);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
			Assert.That(c.Variations.Count, Is.EqualTo(0));
			cv = s.CreateCriteria<ContractVariation>().UniqueResult<ContractVariation>();
			Assert.That(cv, Is.Null);
			s.Delete(c);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<ContractVariation>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(1);
		}
		public virtual void RemoveOneToManyElementByDelete()
		{
			ClearCounts();
	
			Contract c = new Contract(null, "gail", "phone");
			Party party = new Party("party");
			c.AddParty(party);
	
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(c);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			c.RemoveParty(party);
			Assert.That(c.Parties.Count, Is.EqualTo(0));
			if (isContractPartiesBidirectional)
			{
				Assert.That(party.Contract, Is.Null);
			}
	
			s = OpenSession();
			t = s.BeginTransaction();
			s.Update(c);
			s.Delete(party);
			t.Commit();
			s.Close();
	
			AssertUpdateCount(isContractVersioned ? 1 : 0);
			AssertDeleteCount(1);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
			Assert.That(c.Parties.Count, Is.EqualTo(0));
			s.Delete(c);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Party>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(1);
		}
		public virtual void RemoveOneToManyElementUsingMerge()
		{
			ClearCounts();
	
			Contract c = new Contract(null, "gail", "phone");
			Party party = new Party("party");
			c.AddParty(party);
	
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(c);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			c.RemoveParty(party);
			Assert.That(c.Parties.Count, Is.EqualTo(0));
			if (isContractPartiesBidirectional)
			{
				Assert.That(party.Contract, Is.Null);
			}
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = (Contract)s.Merge(c);
			party = (Party)s.Merge(party);
			t.Commit();
			s.Close();
	
			if (CheckUpdateCountsAfterRemovingElementWithoutDelete())
			{
				AssertUpdateCount(isContractVersioned && !isContractPartiesInverse ? 1 : 0);
			}
			AssertDeleteCount(0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
			if (isContractPartiesInverse)
			{
				Assert.That(c.Parties.Count, Is.EqualTo(1));
				party = c.Parties.First();
				Assert.That(party.Name, Is.EqualTo("party"));
				Assert.That(party.Contract, Is.SameAs(c));
			}
			else
			{
				Assert.That(c.Parties.Count, Is.EqualTo(0));
				party = s.CreateCriteria<Party>().UniqueResult<Party>();
				if (isContractPartiesBidirectional)
				{
					Assert.That(party.Contract, Is.Null);
				}
				s.Delete(party);
			}
			s.Delete(c);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Party>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(2);
		}
		public virtual void MoveOneToManyElementToExistingEntityCollection()
		{
			ClearCounts();
	
			Contract c = new Contract(null, "gail", "phone");
			c.AddParty(new Party("party"));
			Contract c2 = new Contract(null, "david", "phone");
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(c);
			s.Persist(c2);
			t.Commit();
			s.Close();
	
			AssertInsertCount(3);
			AssertUpdateCount(0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().Add(Restrictions.IdEq(c.Id)).UniqueResult<Contract>();
			Assert.That(c.Parties.Count, Is.EqualTo(1));
			Party party = c.Parties.First();
			Assert.That(party.Name, Is.EqualTo("party"));
			if (isContractPartiesBidirectional)
			{
				Assert.That(party.Contract, Is.SameAs(c));
			}
			c.RemoveParty(party);
			c2 = s.CreateCriteria<Contract>().Add(Restrictions.IdEq(c2.Id)).UniqueResult<Contract>();
			c2.AddParty(party);
			t.Commit();
			s.Close();
	
			AssertInsertCount(0);
			AssertUpdateCount(isContractVersioned ? 2 : 0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().Add(Restrictions.IdEq(c.Id)).UniqueResult<Contract>();
			c2 = s.CreateCriteria<Contract>().Add(Restrictions.IdEq(c2.Id)).UniqueResult<Contract>();
			if (isContractPartiesInverse)
			{
				Assert.That(c.Parties.Count, Is.EqualTo(1));
				party = c.Parties.First();
				Assert.That(party.Name, Is.EqualTo("party"));
				if (isContractPartiesBidirectional)
				{
					Assert.That(party.Contract, Is.SameAs(c));
				}
				Assert.That(c2.Parties.Count, Is.EqualTo(0));
			}
			else
			{
				Assert.That(c.Parties.Count, Is.EqualTo(0));
				Assert.That(c2.Parties.Count, Is.EqualTo(1));
				party = c2.Parties.First();
				Assert.That(party.Name, Is.EqualTo("party"));
				if (isContractPartiesBidirectional)
				{
					Assert.That(party.Contract, Is.SameAs(c2));
				}
			}
			s.Delete(c);
			s.Delete(c2);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Party>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(3);
		}
		public virtual void CreateWithNonEmptyOneToManyCollectionMergeWithNewElement()
		{
			ClearCounts();
	
			Contract c = new Contract(null, "gail", "phone");
			Party party = new Party("party");
			c.AddParty(party);
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(c);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			Party newParty = new Party("new party");
			c.AddParty(newParty);
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = (Contract)s.Merge(c);
			t.Commit();
			s.Close();
	
			AssertInsertCount(1);
			AssertUpdateCount(isContractVersioned ? 1 : 0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
			Assert.That(c.Parties.Count, Is.EqualTo(2));
			foreach (Party aParty in c.Parties)
			{
				if (aParty.Id == party.Id)
				{
					Assert.That(aParty.Name, Is.EqualTo("party"));
				}
				else if (!aParty.Name.Equals(newParty.Name))
				{
					Assert.Fail("unknown party:" + aParty.Name);
				}
				if (isContractPartiesBidirectional)
				{
					Assert.That(aParty.Contract, Is.SameAs(c));
				}
			}
			s.Delete(c);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Party>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(3);
		}
		public virtual void CreateWithNonEmptyOneToManyCollectionOfExisting()
		{
			ClearCounts();
	
			Party party = new Party("party");
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(party);
			t.Commit();
			s.Close();
	
			AssertInsertCount(1);
			AssertUpdateCount(0);
			ClearCounts();
	
			Contract c = new Contract(null, "gail", "phone");
			c.AddParty(party);
			s = OpenSession();
			t = s.BeginTransaction();
			s.Save(c);
			t.Commit();
			s.Close();
	
			AssertInsertCount(1);
			// BUG, should be assertUpdateCount( ! isContractPartiesInverse && isPartyVersioned ? 1 : 0 );
			AssertUpdateCount(0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
			if (isContractPartiesInverse)
			{
				Assert.That(c.Parties.Count, Is.EqualTo(0));
				party = s.CreateCriteria<Party>().UniqueResult<Party>();
				Assert.That(party.Contract, Is.Null);
				s.Delete(party);
			}
			else
			{
				Assert.That(c.Parties.Count, Is.EqualTo(1));
				party = c.Parties.First();
				Assert.That(party.Name, Is.EqualTo("party"));
				if (isContractPartiesBidirectional)
				{
					Assert.That(party.Contract, Is.SameAs(c));
				}
			}
			s.Delete(c);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Party>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0));
			t.Commit();
			s.Close();
	
			AssertUpdateCount(0);
			AssertDeleteCount(2);
		}
		public virtual void OneToManyCollectionOptimisticLockingWithUpdate()
		{
			ClearCounts();
	
			Contract cOrig = new Contract(null, "gail", "phone");
			Party partyOrig = new Party("party");
			cOrig.AddParty(partyOrig);
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			s.Persist(cOrig);
			t.Commit();
			s.Close();
	
			AssertInsertCount(2);
			AssertUpdateCount(0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			Contract c = s.Get<Contract>(cOrig.Id);
			Party newParty = new Party("new party");
			c.AddParty(newParty);
			t.Commit();
			s.Close();
	
			AssertInsertCount(1);
			AssertUpdateCount(isContractVersioned ? 1 : 0);
			ClearCounts();
	
			s = OpenSession();
			t = s.BeginTransaction();
			cOrig.RemoveParty(partyOrig);
			s.Update(cOrig);
			try
			{
				t.Commit();
				Assert.That(isContractVersioned, Is.False);
			}
			catch (StaleObjectStateException)
			{
				Assert.That(isContractVersioned, Is.True);
				t.Rollback();
			}
			s.Close();
	
			s = OpenSession();
			t = s.BeginTransaction();
			c = s.CreateCriteria<Contract>().UniqueResult<Contract>();
			s.CreateQuery("delete from Party").ExecuteUpdate();
			s.Delete(c);
			Assert.That(s.CreateCriteria<Contract>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			Assert.That(s.CreateCriteria<Party>().SetProjection(Projections.RowCountInt64()).UniqueResult<long>(), Is.EqualTo(0L));
			t.Commit();
			s.Close();
		}