Hibernate version: 1.0.2
Mapping documents:
code
Code:
public class SubscriptionParameter : ILifecycle
{
private Subscription subscription;
private TopicParameter topicParameter;
private String value;
public TopicParameter TopicParameter
{
get { return topicParameter; }
set { topicParameter = value; }
}
public string Value
{
get { return this.value; }
set { this.value = value; }
}
[XmlIgnore]
public Subscription Subscription
{
get { return subscription; }
set { subscription = value; }
}
public LifecycleVeto OnSave(ISession s)
{
//Do something
return LifecycleVeto.NoVeto;
}
public LifecycleVeto OnUpdate(ISession s)
{
//Do something
return LifecycleVeto.NoVeto;
}
public LifecycleVeto OnDelete(ISession s)
{
//Do something
return LifecycleVeto.NoVeto;
}
public void OnLoad(ISession s, object id)
{
}
}
mappingCode:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="Ft.NotificationService.Business.Entity.SubscriptionParameter, Ft.NotificationService.Business" table="SubscriptionParameter" lazy="false">
<composite-id>
<key-many-to-one name="TopicParameter" column="TopicParameterId"/>
<key-many-to-one name="Subscription" column="SubscriptionId"/>
</composite-id>
<property name="Value" not-null="true" type="AnsiString" length="9000"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
ISession session = null;
ITransaction transaction = null;
session = sessionFactory.openSession();
transaction = session.BeginTransaction();
SubscriberManager subscriberManager = SubscriberManager.GetInstance();
Subscriber subscriber = subscriberManager.FindById(53, session);
TopicManager topicManager = TopicManager.GetInstance();
Topic topic = topicManager.FindByAlias("CARDNOTIFICATIONS", session);
SubscriptionManager subscriptionManager = SubscriptionManager.GetInstance();
Subscription subscription = new Subscription();
TopicParameterManager topicParameterManager = TopicParameterManager.GetInstance();
TopicParameter topicParameter = topicParameterManager.FindByAliasAndTopicAlias("CARDNUMBER", "CARDACCOUNTNOTIFICATIONS", session);
subscription.WasLastInvokeSuccesfull = DBNull.Value;
subscription.Topic = topic;
subscription.Subscriber = subscriber;
subscription.LastInvokeTime = DBNull.Value;
subscription.IsStopped = false;
subscription.IsDeleted = false;
session.Save(subscription);
SubscriptionParameter subscriptionParameter = new SubscriptionParameter();
subscriptionParameter.Value = "val";
subscriptionParameter.TopicParameter = topicParameter;
subscriptionParameter.Subscription = subscription;
session.Save(subscriptionParameter);
subscriptionParameter.Value = "val1";
session.Update(subscriptionParameter);
transaction.Commit();
session.Close();
Console.ReadLine();
Name and version of the database you are using: MS SQL Server 2000
Hi all!
A have been confronted with the following problem: I have an object implementing ILifecycle. So, I need to make 3 handlers for 3 events (Save, Delete and Update). How it's written in NHibernate documentation, that ILifecycle Methods OnSave, OnUpdate and OnDelete methods will be called, when that events occurs. OnSave and OnDelete are OK, but there are mistake when Update happens, and OnUpdate method is not called!
Next thing, I've taken NHibernate sources and begin to look what's happening there. And I found next code:Code:
CheckIsOpen();
if( obj == null )
{
throw new ArgumentNullException( "obj", "attempted to update null" );
}
if( ReassociateIfUninitializedProxy( obj ) )
{
return;
}
object theObj = UnproxyAndReassociate( obj );
IClassPersister persister = GetPersister( theObj );
if( IsEntryFor( theObj ) )
{
[b]//here we have a problem: we should envoke onUpdate method, but we do not envoke anything, the fact that object implements ILifecycle is simply ignored.[/b]
log.Debug( "object already associated with session" );
// do nothing
}
else
{
// the object is transient
object id = persister.GetIdentifier( theObj );
if( id == null )
{
// assume this is a newly instantiated transient object
throw new HibernateException( "The given object has a null identifier property " + MessageHelper.InfoString( persister ) );
}
else
{
DoUpdate( theObj, id, persister );
}
}
it's Impl/SessionImpl.cs line 1462
my solution was the simpliest thing I could thought out - I have written the following:
Code:
if( IsEntryFor( theObj ) )
{
object id = persister.GetIdentifier( theObj );
if( id == null )
{
// assume this is a newly instantiated transient object
throw new HibernateException( "The given object has a null identifier property " + MessageHelper.InfoString( persister ) );
}
if( persister.ImplementsLifecycle )
{
log.Debug( "calling onUpdate()" );
if( ( ( ILifecycle ) obj ).OnUpdate( this ) == LifecycleVeto.Veto )
{
log.Debug( "update vetoed by onUpdate()" );
Reassociate( obj, id, persister );
return;
}
}
log.Debug( "object already associated with session" );
// do nothing
}
May be it's stupid, but I really cant understand all the logic of NHibernate in several hours to write something more complicated. I hope the developers will fix that problem as it should be in next version!
Sorry for awful english!