I have an error "The column 'Translat2_' was specified multiple times for 'query'" when using paging for my query.
My classes hierarchy:
Politician
--PoliticianInFactions : PoliticianInFaction
--EntityTranslations : Translation
Faction
--PoliticiansInFaction : PoliticianInFaction
--EntityTranslations : Translation
Translation
--Name : String
--Language : Language
What I want: to fetch politicians ordered by its faction's name and than by its name.
My query:
var criteria = Session.CreateCriteria<Politician>("politician");
// criteria for current faction
var currentFactionCriteria = criteria
.CreateCriteria<Politician>(x => x.PoliticianInFactions, JoinType.InnerJoin)
.Add<PoliticianInFaction>(x => x.FromDate <= DateTime.Now)
.CreateCriteria<PoliticianInFaction>(x => x.Faction, JoinType.InnerJoin);
// add order by faction's name !!!
currentFactionCriteria
.CreateCriteria<Faction>(x => x.EntityTranslations, JoinType.InnerJoin)
.Add<Translation>(x => x.Language.Id == languageId)
.AddOrder<CityTranslation>(x => x.Name, Order.Asc);
// add order by politician's name !!!
criteria
.CreateCriteria<Politician>(x => x.EntityTranslations, JoinType.InnerJoin)
.Add<Translation>(x => x.Language.Id == languageId)
.AddOrder<Translation>(x => x.Name, Order.Asc);
When adding paging to this query I have an error. Without paging everything is OK. Also if I comment(remove) any block marked with (!!!) exception dissapears.
What am I doing wrong? If this is a bug of NHibernate give me some workaround please. Thank you.
Check you mapping files to see if you have mapped multiple properties to the same database column or mapped the same databases column to multiple properties.
I know that this is an ancient thread, but this issue plagued me recently.
I've discovered that the case of the property calls in your mapping matters relative to paging. I.E. if you have a property with a column called "field" and you map it to another property as well, this will not be an issue if the case of field is the same.
However, if you identify your other mapping with a column called "Field", paging will not know that this is not a distinct property and will try to query the same column twice!
I guess that you have a CASE or duplicate problem.In my issue I have the following situation:
I take the column "serie id" two times but in different ways.. I put "S" in lower and in upper.. I hope that helps..
Related
I have created a new extension with the extension builder which includes some tables and inline relations between some tables.
For reporting I need some queries where the selection condition is based on the related records.
Here I have difficulties to get the data (except doing raw queries, which seems wrong).
attempt:
do the query in the related records and extract the field which holds the uid of the parent records.
Problem: in the query result is no field with the uid of the parent record (although it is in the database).
This is understandable as there are no methods to get/set the relation. (But it does not change if I insert these methods.)
Also in the children record there is no TCA definition of the relation field except:
'parent' => [
'config' => [
'type' => 'passthrough',
],
],
which might be the reason the field can not be displayed in the record even if inserted in the showitem list.
attempt:
doing a join from the parent record.
Here I have not found any examples how to build a join.
There are other possibilities for a query, but the plainest seems this in the parent record repository:
public function getParentsByFilter($mainCondition,$subCondition) {
$parentQuery = $this->createQuery();
$parentQuery->matching(
$parentQuery->logicalAnd(
$parentQuery->equals('parent_field',$mainCondition)
// $childQuery->equals('children_field',$subCondition)
)
);
// $parentQuery->joinTable('tx_myext_domain_model_children', ...)
$parentQuery->setOrderings(['crdate'=> QueryInterface::ORDER_DESCENDING]);
$parentQuery->getQuerySettings()->setRespectStoragePage(false);
return $parentQuery ->execute();
}
Here I don't know how to join the children table.
I expect some methods like the commented lines, but have not found anything like it.
What's about the same configuration like in the table sys_category?
I am trying to extract items from different TypeHierarchies from a single query. 3 of the attributes are from "HierarchicalRequirement" while 3 other are from "PortfolioItem".
My question is, can I mention multiple TypeHierarchies in a single query? in the find, like this:
"find" => {"_ProjectHierarchy" => projectID, "_TypeHierarchy" => ["HierarchicalRequirement","PortfolioItem"] , "ScheduleState" => "Accepted" }
Thanks!
You are correct, the LookbackAPI figures out what field belongs to what hierarchy type.
PortfolioItem has field "State" and HierarchicalRequirement has field "ScheduleState". Just to illustrate your answer for the benefit of other users here is a screenshot of results fragment from a query that specifies two types "_TypeHierarchy":{$in:["PortfolioItem","HierarchicalRequirement"]} :
https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/1111/artifact/snapshot/query.js?find={"_ProjectHierarchy":12352814790, "_TypeHierarchy":{$in:["PortfolioItem","HierarchicalRequirement"]},"__At":"2013-08-01T00Z"}&fields=["_TypeHierarchy","_UnformattedID","ScheduleState","State"]&hydrate=["_TypeHierarchy","ScheduleState","State"]
Ok, I am a little stumped on this NHibernate query. The confusion is around PasswordResetToken.
Firstly, here is the mapping:
public ContactMap()
{
Table("Contact");
Id(x => x.ContactId, "ContactId").Unique().GeneratedBy.Increment();
Map(x => x.EmailAddress);
...
Map(x => x.JobTitle);
References(x => x.PasswordResetToken, "EmailAddress")
.PropertyRef(x => x.EmailAddress)
.Cascade.None()
.Not.LazyLoad()
.Not.Update();
HasMany(x => x.Roles)
.Table("tblContactRole").KeyColumn("ContactId").Element("Role", part => part.Type<global::NHibernate.Type.EnumStringType<ContactRoles>>())
.AsSet()
.Not.LazyLoad();
}
Now here is the query:
public IList<Contact> GetContacts(int id)
{
var contacts = Session.CreateCriteria<Contact>()
.Add(Restrictions.Eq("Id", id))
.Add(Restrictions.Eq("IsActive", true))
.SetFetchMode("Roles", FetchMode.Eager)
.SetFetchMode("PasswordResetToken", FetchMode.Eager)
.SetResultTransformer(CriteriaSpecification.DistinctRootEntity)
.List<Contact>();
return contacts;
}
My understanding is that FetchMode.Eager means a JOIN is used instead of a SUBSELECT, so there isn't any reason there for extra calls to the db to appear.
A correct SQL query is run returning all the information required to hydrate a Contact as evidenced from the screenshot from NHProf (the highlighted query) (dont' worry about different table names etc - I have sanitized the code above):
What I don't understand is why on earth dozens of separate selects to the PasswordResetToken table are generated and run?? One of these queries is only generated for every contact that doesn't have a PasswordResetToken (ie. the first query returns nulls for those columns) - not sure what this has to do with it.
A contact might or might not have a few roles (superfluous to this issue) and similarly, may or may not have exactly one PasswordResetToken.
The DB is a little dodgy with few foreign keys. The link between Contact and PasswordResetToken in this case is a simple shared column "EmailAddress".
All these queries are generated on the running of that single line of code above (ie. that code is not in a loop).
Let me know if I am missing any info.
What should I be googling?
It's a bug. I would try to get it to work with just two queries, although from the bug report it sounds like that will be a challenge.
The attached test shows that a many-to-one association referencing an unique property (instead of the Id) results in a select n+1 problem. Although the first statement contains the correct join, all associated entities are fetched one by one after the join select. (Entities with the same value in the unique column are even fetched more than once.)
The interesting point is that this bug only occurs if the referenced
entities are already in the session cache. If they are not, no
additional select statements are created.
I seem to get an error when querying an object that has a child POCO property object:
could not resolve property: PreferredLanguage.Name of: AcademyData.Entities.StudentsInformation
My query:
Session.QueryOver<StudentsInformation>().Where(x => x.Active == 1 && x.PreferredLanguage.Name == firstName).List()
If I remove the x.PreferredLanguage.Name criteria, it works, and I see the correct Name value of the object, but it won't let me use it as a query. What am I doing wrong?
Here is my mapping:
References(x => x.PreferredLanguage).Column("PreferredLanguageID");
Also, I've split my POCO's and mappings into 2 seperate assemblies, if that makes any difference. I configure the mapping so:
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<AcademyData.Dummy>().AddFromAssemblyOf<data.core.Dummy>())
Ignore the dummy, was using it to test something.
EDIT: I've tested it using an entity from the same assembly and the problem still exists.
EDIT:
I found a solution to my problem:
return SessionManager.Session.QueryOver<StudentsInformation>().JoinQueryOver<PersonBase>(s => s.Person).Where(p => p.FirstName == firstName).List();
Is this the right way of doing it, or should I still be able to do it without the JoinQueryOver for a different table?
Alternatively, you can use LINQ instead of QueryOver:
return Session.Query<StudentsInformation>()
.Where(x => x.Active == 1 && x.PreferredLanguage.Name == firstName)
.ToList()
You have to join on the child entity if you wish to query by that child entity. That is the correct way of doing it. You could also use JoinAlias if you wish.
I am working with Linq-To-NHibernate. I need to use some properties that is not mapped to columns.
For example
Repository<Person>
.Find()
.Select(p => new PersonModel() { Id = p.Id, FullName= p.FullName,Position = p.Position });
The position is not a mapped property, it contains some logic.
I got unmapped property error.
Thanks.
Not possible, and not likely to be supported in short term.