Using 'Assigned' ID with NHibernate
I have two entities, Job开发者_Python百科 and Language, in a many-to-one relationship. The mapping configuration of these entities is as follows:
public class JobMap : ClassMap<Job>
{
public JobMap()
{
Table("\"JOB\"");
LazyLoad();
Id(x => x.Id, "id").GeneratedBy.HiLo("hilo", "hilo_job", "50");
Map(x => x.Name).Column("name").Unique();
References<Language>(x => x.SourceLanguage, "fk_id_language").Cascade.None();
}
}
public class LanguageMap : ClassMap<Language>
{
public LanguageMap()
{
Table("\"LANGUAGE\"");
LazyLoad();
Id(x => x.Id, "id").GeneratedBy.Assigned().UnsavedValue(0);
Map(x => x.Code).Column("code");
}
}
I use this code to add a job into the database
private IServiceOperationResult AddJob(string jobName, Language sourceLanguage)
{
try
{
ISession session = sessionBuilder.GetSession();
using (ITransaction transaction = session.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
job = new Job(jobName, sourceLanguage);
jobRepository.Add(job);
transaction.Commit();
}
}
catch (Exception e)
{
log.Error("Error adding job to the DB", e);
return new StringServiceOperationResult(e);
}
return new OkOperationResult();
}
The JobRepository.Add(Job job) is simple
public void Add(Job entity)
{
SessionBuilder.GetSession().Save(entity);
}
The problem is that running this code with NHProfiler on, I can see the following warning before INSERT into the JOB table:
WARN: Unable to determine if en-GB with assigned identifier 47 is transient or detached; querying the database. Use explicit Save() or Update() in session to prevent this.
followed by (unnecessary) SELECT from the LANGUAGE table to load the Language entity with the id 47 (where "en-GB" is a code of a Job.SourceLanguage object).
In my case I do not want to ever update, insert or delete a Language entity from the database (in situation where it is just referenced from other entities), it is really immutable table, filled with the correct rows all the time. Is there a way to tell NHibernate to just take the Language from me and when inserting into the JOB table, to use its Id property and not care whether it is present in the database or not?
When I add this line before adding the Job to the repository
job.SourceLanguage = session.Load<Language>(sourceLanguage.Id);
I no longer get the warning nor the SELECT, but it is kind of cumbersome to do this everywhere I work with the Language entity.
Thank you very much.
An option is to use interceptor class! Override OnSave method adding this
job.SourceLanguage = session.Load<Language>(sourceLanguage.Id);
when the entity is "Job". In this way you don't have to do this query everywhere.
Look here for example:
Sample NHibernate IInterceptor implementation
精彩评论