-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Read stored proc results without a mapping table?
PostPosted: Sat Sep 30, 2006 4:01 am 
Newbie

Joined: Sat Sep 30, 2006 3:32 am
Posts: 3
Hi,

Is it possible for NHibernate to read the results of a stored procedure into a set/list/collection of strictly *read-only* objects that are not mapped/bound to an actual table? The data is actually generated by a complex select query against a remote SQL server; and I need to keep this separate from the hbm xml mapping files.

First I tried the read-only cache within <class> element, but there is no table for me to specify so it would not work.

Next I tried using <sql-query> element but it fails with "No persistor for: <<classname>>". Details below.

Please let me know if NHibernate was even designed to support this. If not I can use ADO.NET, but I would prefer NHibernate.

Thanks
Chris


NHibernate version:
1.2.0.Beta1
Mapping documents:
<sql-query name="spGetCompanies" >
<return alias="companylist" class="Test.Company, Test.Data">
<return-property column="DateOfOriginalInvestment" name="DateOfOriginalInvestment" />
<return-property column="InitialCost" name="InitialCost" />
<return-property column="EnterpriseValue" name="EnterpriseValue" />
</return>
exec spGetCompanies
</sql-query>

Code between sessionFactory.openSession() and session.close():
IQuery q = sess.GetNamedQuery("spGetCompanies");
IList result = q.List();

Full stack trace of any exception that occurs:
NHibernate.MappingException: No persister for: Test.Company, Test.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1b66c4a630e22817
at NHibernate.Impl.SessionFactoryImpl.GetEntityPersister(String className, Boolean throwIfNotFound)
at NHibernate.Impl.SessionFactoryImpl.GetEntityPersister(String className)
at NHibernate.Loader.Custom.SQLQueryReturnProcessor.GetSQLLoadable(String entityName)
at NHibernate.Loader.Custom.SQLQueryReturnProcessor.ProcessRootReturn(SQLQueryRootReturn rootReturn)
at NHibernate.Loader.Custom.SQLQueryReturnProcessor.ProcessReturn(ISQLQueryReturn rtn)
at NHibernate.Loader.Custom.SQLQueryReturnProcessor.Process()
at NHibernate.Loader.Custom.SQLCustomQuery..ctor(ISQLQueryReturn[] queryReturns, String sqlQuery, ICollection additionalQuerySpaces, ISessionFactoryImplementor factory)
at NHibernate.Impl.SessionImpl.List(NativeSQLQuerySpecification spec, QueryParameters queryParameters, IList results)
at NHibernate.Impl.SessionImpl.List(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
at NHibernate.Impl.SqlQueryImpl.List()
at Test.DataManager.GetCompanies() in C:\Test\DataManager.cs:line 1223
at Test.PortfolioCompany.button2_Click(Object sender, EventArgs e) in C:\Test\PortfolioCompany.Test.cs:line 82
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Test.Program.Main() in C:\Test\Program.cs:line 21

Name and version of the database you are using:
MS SQL 2005

Debug level Hibernate log excerpt:

2006-09-30 03:40:41,758 [5548] DEBUG NHibernate.Impl.SessionImpl::opened session
2006-09-30 03:40:43,102 [5548] DEBUG NHibernate.Loader.Custom.SQLCustomQuery::starting processing of sql query [exec spGetCompanies]


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 30, 2006 12:42 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Create a query returning just the columns and use a result transformer in the code:
Code:
IQuery query = session.GetNamedQuery("...").SetResultTransformer(Transformers.AliasToBean(typeof(Company)));

Note that Company will have to have read-write properties for this to work. You can also write a custom result transformer if you are not satisfied with this.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 30, 2006 5:28 pm 
Newbie

Joined: Sat Sep 30, 2006 3:32 am
Posts: 3
Awesome, it works.

Thank you Sergey for the quick reply, my faith is renewed !!!

Regards,
Chris


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 7:23 am 
Newbie

Joined: Wed May 17, 2006 7:06 pm
Posts: 3
hi sergey,

I am not able get the result with the method you propose when i do a stored procedure. I still have an error "No persistor for: <<classname>>".
here is a snipplet of my code.

...
return
.Session
.GetNamedQuery("GetEpisodeEncounterByPatientId")
.SetInt32(0, PatientOID)
.SetResultTransformer(Transformers.AliasToBean(typeof(EpisodeEncounterInfo)))
.List<EpisodeEncounterInfo>();
...

hbm file
<sql-query name="GetEpisodeEncounterByPatientId" flush-mode ="never">
<return class ="Nhg.Plato.Entities.RIM.PatientAdministration.EpisodeEncounterInfo,Nhg.Plato.Entities" lock-mode ="read">
<return-property column ="OID" name ="EncounterOID"/>
</return>
<![CDATA[
select
ep.oid as EncounterOID
from
pat_episodeencounteract_tx ep
inner join
pat_patientrol_tx pat
on
pat.oid=ep.patientoid
where
pat.oid=?
]]>
</sql-query>

entity class
namespace Nhg.Plato.Entities.RIM.PatientAdministration
{
public class EpisodeEncounterInfo
{

private int _encounteroid;
private string _caseTypeCode;
private string _caseTypeDesc;
private IList<PatientEncounterInfo> _patientEncounters;

public IList<PatientEncounterInfo> PatientEncounters
{
get { return _patientEncounters;}
set { _patientEncounters = value;}
}

public int EncounterOID
{
get { return _encounteroid; }
set { _encounteroid = value; }
}

public string CaseTypeCode
{
get { return _caseTypeCode; }
set { _caseTypeCode = value; }
}

public string CaseTypeDesc
{
get { return _caseTypeDesc; }
set { _caseTypeDesc = value; }
}
}
}


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 21, 2006 8:44 pm 
Beginner
Beginner

Joined: Mon Aug 15, 2005 11:50 pm
Posts: 22
hendry78,

have you been able to solve the no persisister for xxx error yet? I am receiving it calling a stored proc and I have what I think is a valid class to persist it to.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 21, 2006 11:11 pm 
Beginner
Beginner

Joined: Mon Aug 15, 2005 11:50 pm
Posts: 22
Ah the penny just dropped I think..

Was trying to populate a MonthlySetTargets class using:

Code:
<sql-query name="MonthlySetTargets_sp">
    <return alias="targets" class="MonthlySetTargets">
      <return-property name="MeasureTypeId" column="MeasureTypeId"/>
      <return-property name="Code" column="Code"/>
      <return-property name="TargetCount" column="TargetCount"/>
    </return>
    exec GetMonthlySetTargets :date, :locationId
  </sql-query>


and kept getting No Persister for <class>.
I had not defined the class in a mapping file since I didn't want nhib to manage it. I didn't really grok what was occuring overall.

Dropped properties and set scalars.

Code:
<sql-query name="MonthlySetTargets_sp">
    <return-scalar column="MeasureTypeId" type="Int32"/>
    <return-scalar column="Code" type="String"/>
    <return-scalar column="TargetCount" type="Int32"/>
    exec GetMonthlySetTargets :date, :locationId
  </sql-query>


Then using
Code:
SetResultTransformer(Transformers.AliasToBean(typeof(MonthlySetTargets )))

on the IQuery and everything is working now.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.