I have the same problem. Im using Criteria to query all the Clients and the clients groups that match the criteria set.
Im using NHibernate 1.2.0 CR1
Code:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:nhibernate-mapping-2.2" default-cascade="save-update">
<class name="Vita.Pesa.Domain.BusinessInfo, Vita.Pesa" lazy="true" table="BusinessInfo">
<id name="Id" column="Id" type="Int32" unsaved-value="0">
<generator class="identity" />
</id>
<property
name="Name"
type="String"
column="Name"
length="200"
not-null="true" />
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:nhibernate-mapping-2.2" default-cascade="save-update">
<joined-subclass
name="Vita.Pesa.Domain.Client, Vita.Pesa"
lazy="true"
extends="Vita.Pesa.Domain.BusinessInfo, Vita.Pesa"
table="Client">
<key column="BusinessInfoId" />
<bag name="ClientGroups" inverse="true" cascade="all-delete-orphan">
<key column="ClientId" />
<one-to-many class="Vita.Pesa.Domain.ClientGroup, Vita.Pesa" />
</bag>
</joined-subclass>
</hibernate-mapping>
namespace Vita.Pesa.Domain {
/// <summary>
/// Client
/// </summary>
[Serializable]
[b]public class Client : BusinessInfo [/b]{
private IList<ClientGroup> _clientGroups;
/// <summary>
/// Gets the client groups.
/// </summary>
/// <value>The client groups.</value>
public virtual IList<ClientGroup> ClientGroups
{
get { return _clientGroups; }
set { if (_clientGroups != value) _clientGroups = value; }
}
}
}
namespace Vita.Pesa.Domain {
/// <summary>
/// Business Info
/// </summary>
[b]public class BusinessInfo [/b]{
private int _id;
private string _name;
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public virtual int Id {
get { return _id; }
set { if (_id != value) _id = value; }
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public virtual string Name {
get { return _name; }
set {
if (String.IsNullOrEmpty(value)) {
throw new PesaArgumentException(Errors.BusinessNameNull);
}
else {
if (value.Length > 200)
throw new PesaArgumentException(Errors.BusinessNameLength);
}
if (_name != value) _name = value;
}
}
}
}
public class [b]ClientGroup [/b]{
}
So i have Tables like this:
BusinessInfoId int
Name nvarchar(200)
ClientBusinessInfoId int (Id from BusinessInfo table)
ClientGroupId int
ClientId int (BusinessInfoId from Client table)
Now i am doing a query like this:Code:
int[] clientGroupIds = new int[] {2, 3};
string name = "ClientName";
ICriteria criteria = Repository.Session.CreateCriteria(typeof(Client));
criteria.CreateCriteria("ClientGroups", "ClientGroups", JoinType.LeftOuterJoin);
criteria.Add(
Expression.And(
Expression.In("ClientGroups.Id", clientGroupIds),
Expression.Like("Name", name, MatchMode.Start)
)
);
return criteria.List<Client>();
Now in the database there is exactly 1 client with name "ClientName" and two ClientGroups with Id -s 2 and 3.
When i make this query i get back a IList<Client> with two Clients (both the same client with two ClientGroups). (What im saying here is that the List has two Client items, which are exactly the same (ID, name etc)).
My only guess is that there are as many clients in the list as there are ClientGroup objects (and this seems to be the case).
I have tryed other criteria queries, but im still getting the same result.
Query generated by nhibernate.Code:
SELECT
this_.BusinessInfoId as Id7_1_, this_1_.Name as Name7_1_, clientgrou1_.ClientId as ClientId__3_, clientgrou1_.Id as Id3_
FROM Client this_
inner join BusinessInfo this_1_ on this_.BusinessInfoId=this_1_.Id
left outer join ClientGroup clientgrou1_ on this_.BusinessInfoId=clientgrou1_.ClientId
WHERE (clientgrou1_.Id in (@p0, @p1) and this_1_.Name like @p2); @p0 = '2', @p1 = '3', @p2 = 'ClientName%'
I dont understand why this duplication is happening, its not mappind the data back right.