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 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 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();
		}
		public virtual void RemoveParty(Party party)
		{
			parties.Remove(party);
			party.Contract = null;
		}
		public virtual void AddParty(Party party)
		{
			parties.Add(party);
			party.Contract = this;
		}