NHibernate: Is it possible to add restriction based on alias name - nhibernate

Say I create a criteria query and transform it with the AliasToBean result transormer.
session.CreateCriteria<Staff>("s")
.CreateAlias("supervisor", "super")
.SetProjection(Projections.ProjectionList()
.Add(Projections.Property("s.name"), "name")
.Add(Projections.Property("super.name"), "supervisor_name"))
.SetResultTransformer(Transformers.AliasToBean<StaffView>());
Is it possible to add a restriction when you only know the property name of the bean? You can AddOrder using the bean property names but the Restrictions only appear to work with the actual property name. I'm guessing this is because they are applied before the transformation, much like you don't use a column alias in a where clause but you can in the order by.
//throws exception like cannot find property supervisor_name in Staff class
//only "super.name" works
.Add(Restrictions.Like("supervisor_name", "blah"))
//this works though
.AddOrder(Order.Asc("supervisor_name"))
So basically I need a way to get the aliased property name based on the alias. I can think of multiple ways to do this, but I was hoping NHibernate had some existing method? I could for example keep a separate map of the property to alias names or just map to a database view so there is no need to transform to bean.

It should work with name of alias dot property name.
{alias}.Name.
Or am I misunderstanding your problem?

Related

Refering to a particular parent, in case of multiple, and then retrieving its attribute

If an sobject has more then one parent, how do we lexically refer any one its parent in order to get its attributes?
I need it to write a naming convention for that particular sobject.
The sobject and its parent sobjects are connected in the schema by code.
What I tried was something like:
{project.code}/{sobject.parent01_code}/{sobject.code}/{context}
which works but {sobject.parent01_code} is not what I want, because it is not quite self-explanatory and cryptic to be used for naming of files and directories.
I rather want to something like ../{sobject.parent01.name}/.. or ../{sobject.parent01_code.name}/.. which returns Reported Error: "too many values to unpack" error.
So how can I achieve such a thing? Given, if I am not wrong, the absence of a full brunt expression language in the setting of naming conventions, which, if a present, would enable something like #SOBJECT(parent01["code", {sobject.parent01_code}]).name.
These are two separate questions but put into one because it relates to one particular problem.
This used to be unsolved in earlier versions of tactic. In 4.1 however, you can also use the expression language in the braces.
ex: {project.code}/{#GET(example/some_stype.name)}/versions
If some_stype is the parent of to the current stype's, you'll get the corresponding sobject's name.

Fluent NHibernate - HasMany mapping with condition

I have a HasMany mapping that needs a condition. I have this partially working, but there's got to be a better way than what I'm doing. The condition I'm using needs to look at a property on another table that I'm joining to. What I have so far is:
HasMany<MetaData>(x => x.MetaData).Table("MetaData")
.KeyColumn("DefinitionID")
.KeyColumn("TableID")
.Where("metadatade1_.SourceTable = 'Providers'")
.Cascade.SaveUpdate();
In the code above, the where clause is referencing "metadatade1_", because it's trying to fully qualify the name, and that is the name NH is generating. I've tried using "MetaDataDefinitions.SourceTable" (MetaDataDef... is the physical table name), and also just "SourceTable" by itself, however none of these worked.
Is there a way to not have it try and fully qualify the name on the condition and just pass "SourceTable='Providers'" OR is there a way I can have it reference the generated name without me having to manually plug it in?
In short, no. The Where method (and respectively the where= attribute in HBM.XML) accept only raw sql, and as such is prone to the problems you're seeing.
Your best option is to not use a collection and instead rely on a query to retrieve your metadata instances.

Hibernate Throws a SQLException When Distinctly Selecting only Two of Three Mapped Columns

I have a table, CityComplete, with columns "USPSCITY", "STATE" and "ZIPCODE"
I have an existing SQLQuery that distinctly selects USPSCITY and STATE based on a fuzzy search. However, when I call list() I get an exception:
19. ResultSet.getString(ZIPCODE)
java.sql.SQLException: Column 'ZIPCODE' not found.
The SQLQuery's entity is set to the CityComplete object.
Is there any way to have Hibernate not try and get ZIPCODE, or have it be part of the result set in some way?
What's the best way to resolve this, other than using Criteria, setting a virtual column with null data, or just getting a full result set and handling distinction on the code side?
When you perform a regular Hibernate query (HQL or Criteria), Hibernate will try to map the resultset based on the properties of the entities which you specified in the mapping. If you are not bringing the "promised" data from the database, you'll need to handle the mapping by yourself, using a ResultTransformer. In this case, you'd still use your CityComplete, but they will be without a ZIPCODE. Unfortunately, there's not much documentation about how to use a ResultTransformer, but you can take a look at the Hibernate's JavaDoc and see if there's one that you could use. If not, you'd need to implement your own:
http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/transform/ResultTransformer.html

How to find table related with an alias in Doctrine ORM query?

I'm using Doctrine ORM 1.2 and Symfony 1.4 and I want to create method in myUser class which will extend Doctrine_Query instance passed as an argument with some additional left joins and conditions. The trick is that I don't always want these these left joins to be made with root component of the query and I need to know with what table (record class) the alias corresponds - in some cases I would like to pass an alias of another component and expect it to be supplemented with some extra left joins and conditions.
My question is how can I check what component (essentially table) represents given alias? Suppose I create a Doctrine_Query instance:
$query = Doctrine_Query::create();
$query->from('Folder f')->leftJoin('f.ChildFolders cf');
Now I want my method in myUser class to add some joins to the table with alias 'cf' but varying depending on table which 'cf' aliases. I want to call it this way:
$this->getUser()->limitQueryResultsWithSomeCondition($query, 'cf');
That should return query with additional elements. How can I find out what table is symbolized by 'cf' alias and whether it exists at all in given query?
It is quite straightforward when it is root table of a query that needs to be extended, but I cannot find a way to do it in other cases.
I guess I found my own solution to the problem. To find out to which table/record given alias corresponds one has to use getQueryComponent method. Suppose the query is same as in question above. The solution then reads as follows:
$alias = 'cf';
$query->getSqlQuery();
$component = $query->getQueryComponent($alias);
$recordClass = get_class($component['table']->getRecordInstance());
The trick is that before method getSqlQuery (or some method which is called inside of this method) is called the component will not be found and exception will be thrown.

NHibernate: Return A Constant In HQL

I need to return a constant from an HQL query in NHIbernate
SELECT new NDI.SomeQueryItem(user, account, " + someNumber + ")
FROM NDI.SomeObject object
I am trying for something like above. I've tried this:
SELECT new NDI.SomeQueryItem(user, account, :someNumber)
FROM NDI.SomeObject object
And then later:
.SetParameter("someNumber", 1).List<SomeQueryItem>();
But in the first case I get a 'Undefined alias or unknown mapping 1'. Which makes some sense since it probably thinks the 1 is an alias.
For the second I get a 'Undefined alias or unknown mapping :someNumber' which again makes some sense if it never set the parameter.
I have to believe there's some way to do this.
Please feel free to continue to believe there is some way to do this - but with HQL there isn't!
Why would you want to anyway? If you want to update the value this property to the value you specify, then do so after you've loaded the objects. Alternatively, if your result set doesn't quite match to your objects, you could alway use a SQL query (which you can still do via an NHibernate session). But the purpose of NHibernate is to map what's in your database onto objects, so specifying a manual override like this is quite rightly not allowed.
It sounds like there is a (small?) disconnect between your domain objects and your database model. What about creating a small "DTO" object to bridge this gap?
Have your query return a list of SomeQueryItemDTO (or whatever you want to call it) which, due to the naming, you know is not a true part of your domain. Then have some function to process the list and build a list of true SomeQueryItem objects by incorporating the data that is extraneous to the database.
If you're already using the Repository Pattern, this should be easier since all the ugly details are hidden inside of your repository.