NHibernate Repository pattern problem - nhibernate

I am using NHibernate and Repository patterns in my application. But not want to use UnitofWork pattern.
There are two types of forms in my app. Collection/Picker forms and Entity forms.
But the problem occurs when a form is ShowDialog()ged from within another form.
Whwn I am doing any database related operation, NHibernate is giving me "a different object with the same identifier value was already associated with the session: XYZ" error. This is caused due to the delayed call of Dispose method by CLR and another part of my problem is in the Session management as far as I guess.
How can I change my repository codes to solve my problem?
Remember, I don't want to expose separate BeginTransaction(), CommitTransaction() like functions in my Repository. These things should be embedded within every Method {SaveOrUpdate(), Save(), Delete, Load(), etc.} as I have already done.
Please tell me how can I get things going with minor changes?
I am doing my things like this:
A picker form works like this,
private void btnPick_Click(object sender, EventArgs e)
{
CourseCollectionForm f = new CourseCollectionForm();
f.FormViewMode = FormViewMode.MultiplePicker;
f.ShowDialog();
int totalCredits = 0;
int totalHours = 0;
FillDataGridViewWithCourses(f.PickedCourseCollection, ref totalCredits, ref totalHours);
FillTotal(totalCredits, totalHours);
}
A Save works like this,
public partial class DepartmentEntityForm : Form
{
private DepartmentRepository _deptRepository = null;
private Department _currentDepartment = null;
private FormViewMode _currentMode = FormViewMode.None;
public DepartmentEntityForm(Department dept, FormViewMode mode)
{
InitializeComponent();
_deptRepository = new DepartmentRepository();
_currentDepartment = dept;
_currentMode = mode;
if(mode == FormViewMode.Edit)
{
MapObjectToControls();
}
}
private void SaveButton_Click(object sender, EventArgs e)
{
Department newDept;
if (mode == FormViewMode.AddNew)
{
newDept = new Department();
}
else if(mode == FormViewMode.Edit)
{
newDept = _currentDepartment;
}
//.............
//.............
_deptRepository.SaveOrUpdate(newDept);
}
}
I declare my individual repositories like this:
FacultyRepository.cs
public class FacultyRepository : Repository<Faculty>
{
}
DepartmentRepository.cs
public class DepartmentRepository : Repository<Department>
{
}
Repository.cs
public class Repository<T> : IRepository<T>
{
ISession _session;
public Repository()
{
_session = SessionFactory.GetOpenSession();
}
public T Get(object id)
{
T obj = default(T);
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
obj = (T)_session.Get<T>(id);
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
return obj;
}
public IEnumerable<T> Get(string fieldName, object fieldValue)
{
IEnumerable<T> list = null;
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
list = (IEnumerable<T>)_session.CreateCriteria(typeof(T))
.Add(new NHibernate.Expression.EqExpression(fieldName, fieldValue))
.List<T>();
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
return list;
}
public IEnumerable<T> Get()
{
IEnumerable<T> list = null;
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
list = (IEnumerable<T>)_session.CreateCriteria(typeof(T)).List<T>();
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
return list;
}
public void SaveOrUpdate(T obj)
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
_session.SaveOrUpdateCopy(obj);
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
}
public void SaveOrUpdate(IEnumerable<T> objs)
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
foreach (T obj in objs)
{
_session.SaveOrUpdate(obj);
}
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
}
public void Delete(T obj)
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
_session.Delete(obj);
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
}
public void Delete(IEnumerable<T> objs)
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
foreach (T obj in objs)
{
_session.Delete(obj);
}
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
}
public void DeleteAll()
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
DetachedCriteria criterion = DetachedCriteria.For<T>();
IList<T> list = criterion.GetExecutableCriteria(_session).List<T>();
foreach (T item in list)
{
_session.Delete(item);
}
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
throw ex;
}
}
public void Dispose()
{
if (_session != null)
{
_session.Clear();
_session.Close();
_session = null;
}
}
}
SessionFactory.cs
public class SessionFactory
{
private static ISessionFactory _sessionFactory = null;
private SessionFactory(){}
static SessionFactory()
{
if (_sessionFactory == null)
{
Configuration configuration = new Configuration();
configuration.Configure();
_sessionFactory = configuration.BuildSessionFactory();
}
}
public static ISession GetOpenSession()
{
return _sessionFactory.OpenSession();
}
}

OK guys! It has been long since I posted my question and nobody tends to answer it.
I solved it by making ISession static in the SessionFactory and instead of returning a Open ISession for each Repository, I am returning only one static ISession.

Related

How do I return an InternalErrorResult?

I am using Swagger with a .Net Core API.
When there is a bug in the API I want to receive an InternalServerError
However there is no NotOK method to do this.
Currently I have the following in my base controller
using System;
using Microsoft.AspNetCore.Mvc;
namespace MyApi.Controllers
{
public class BaseController : Controller
{
public IActionResult RouteInterfaceMethod<TResponse>(Func<TResponse> function)
{
// try
// {
IActionResult res = null;
TResponse ret = function();
res = Ok(ret);
return res;
// }
// catch (Exception e)
// {
// var msg = MakeErrorMessage(e);
// return base.NotFound( msg);
// }
}
}
}
And am about to un-comment the code ,is there an alternative to using NotFound()
You can return InternalServerError in this way
catch (Exception e)
{
var msg = MakeErrorMessage(e);
return StatusCode(HttpStatusCode.InternalServerError, msg);
}
or just re-throw an exception
catch (Exception e)
{
var msg = MakeErrorMessage(e);
throw;
}

Create a Generic AttributeConverter[JDO] with JsonConverter

I´m using JDO + DataNucleus and implement a AttributeConverter with Jackson Json.
Already have a generic method for AttributeConverter:
#Override
public String convertToDatastore(ArrayList<Object> alist) {
String jsonString = null;
try {
jsonString = mapper.writeValueAsString(alist);
} catch (IOException e) {
e.printStackTrace();
}
return jsonString;
}
But, in Deserialize JSON to Object i read that i need to specify the class
public ArrayList<TelephoneNumber> convertToAttribute(String s) {
ArrayList<TelephoneNumber> obj = null;
try
{
obj = mapper.readValue(s, mapper.getTypeFactory().constructCollectionType(
List.class, TelephoneNumber.class));
}
catch (JsonParseException e) { e.printStackTrace();}
catch (JsonMappingException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
return obj;
}
but jsonString is a arrayList object
how can I do this?
thanks

JList blank, not displaying anything. Have tried everything other websites suggested

Here:
private static DefaultListModel qpape;
//#SuppressWarnings("null")
public void disp() throws SQLException
{
qpape=new DefaultListModel();
jList2=new JList(qpape);
String sql1="SELECT URL from RECORD";
PreparedStatement st = db.conn.prepareStatement(sql1,
Statement.RETURN_GENERATED_KEYS);
ResultSet rs1=st.executeQuery(sql1);
while(rs1.next())
{
String lnk=rs1.getString("URL");
System.out.println(lnk);
//qpape.addElement(lnk);
((DefaultListModel)jList2.getModel()).addElement(lnk);
}
rs1.close();
}
public static void main(String args[]) throws SQLException, IOException {
fetch();
Qpapers obj=new Qpapers();
if(obj!=null) {
obj.disp();
jList2.setModel(qpape);
}
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info :
javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Qpapers.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Qpapers.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Qpapers.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Qpapers.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Qpapers().setVisible(true);
}
});
}
// Variables declaration - do not modify
private static javax.swing.JList jList2;
private javax.swing.JScrollPane jScrollPane2;
// End of variables declaration
}

calling alarm from a service

I designed my service as it will make an alarm when user will go to a certain location.
But it crashes when it go to the certain making the alarm.
public class CheckDestinationService extends Service {
Calendar calender;
double late,longe;
int dis;
String loc;
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 0;
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
public void onLocationChanged(Location location) {
mLastLocation.set(location);
final double currlat;
final double currlong;
float[] DistanceArray = new float[1];
currlat = location.getLatitude();
currlong = location.getLongitude();
android.location.Location.distanceBetween(currlat,currlong,late,longe,DistanceArray);
float Distance = DistanceArray[0];
//Toast.makeText(getApplicationContext(), "asdf "+String.valueOf(Distance), Toast.LENGTH_SHORT).show();
Log.d("asdfasdas", String.valueOf(currlat)+","+String.valueOf(currlong)+" "+String.valueOf(Distance));
if (Distance<=dis && Distance!=0 && dis!=0)
{
dis = 0;
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Toast.makeText(getApplicationContext(), "Reached "+String.valueOf(Distance), Toast.LENGTH_SHORT).show();
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calender.getTimeInMillis(),pendingIntent);
//stopSelf();
}
/*final Handler handler = new Handler();
Runnable r = new Runnable() {
public void run() {
// TODO Auto-generated method stub
Intent intent = null;
intent.putExtra("lat", currlat);
intent.putExtra("long", currlong);
intent.putExtra("dis", dis);
intent.putExtra("loc", loc);
Toast.makeText(getApplicationContext(), "Sending", Toast.LENGTH_SHORT).show();
sendBroadcast(intent);
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);*/
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
late = intent.getDoubleExtra("lat", 0);
longe = intent.getDoubleExtra("long", 0);
dis = intent.getIntExtra("dis", 0);
loc = intent.getStringExtra("loc");
Toast.makeText(getApplicationContext(), "Destination Set to: "+loc+
" and Minimum Distance: "+
String.valueOf(dis) , Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onCreate() {
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(), "Service Destroyed", Toast.LENGTH_SHORT).show();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
}
}
}
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
}
and my AlarmReceiver class is
public class AlarmReceiver extends Activity {
private MediaPlayer mMediaPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.alarmreceiver);
Button stopAlarm = (Button) findViewById(R.id.stopAlarm);
stopAlarm.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
stopService(new Intent(AlarmReceiver.this, CheckDestinationService.class));
mMediaPlayer.stop();
finish();
return false;
}
});
playSound(this, getAlarmUri());
}
private void playSound(Context context, Uri alert) {
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(context, alert);
final AudioManager audioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
} catch (IOException e) {
System.out.println("OOPS");
}
}
//Get an alarm sound. Try for an alarm. If none set, try notification,
//Otherwise, ringtone.
private Uri getAlarmUri() {
Uri alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alert == null) {
alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (alert == null) {
alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
}
}
return alert;
}
#Override
public void onBackPressed() {
//MainActivity.iMinDistance = 0;
stopService(new Intent(AlarmReceiver.this, CheckDestinationService.class));
mMediaPlayer.stop();
finish();
}
}
I tested AlarmReceiver class from other activites and it worked properly
but it not working from the service.
please help!!
initalize Calendar
calender = Calendar.getInstance()

NHibernate session management

I use NHiberante at my win service. Sometimes I get
System.ObjectDisposedException: Session is closed!
Object name: 'ISession'.
at NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed()
at NHibernate.Impl.AbstractSessionImpl.CheckAndUpdateSessionStatus()
at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.Save(Object obj)
at Attraction.DAL.Repositories.Repository`1.Save(T entity)
at Attraction.VideoDispatcher.Program.ThreadPoolCallback(Object threadContext)
I have no idea what's wrong.
My session management subsystem:
Repository:
public class Repository<T> : IRepository<T>, IDisposable
{
protected readonly bool CommitAtDispose;
public Repository(bool commitAtDispose)
{
CommitAtDispose = commitAtDispose;
StartSession();
}
private void StartSession()
{
if (NHibernateSession == null)
NHibernateHelper.StartSession();
}
public void Dispose()
{
if (CommitAtDispose)
Flush();
}
public void Flush()
{
NHibernateHelper.EndSession();
}
protected override sealed ISession NHibernateSession
{
get
{
return SessionManager.CurrentSession;
}
}
public virtual T GetById(int id)
public virtual List<T> GetAll()
public virtual List<T> GetByPage(int pageIndex, int pageSize)
public virtual int GetCount()
public virtual List<T> GetByCriteria(params ICriterion[] criterion)
public virtual T Save(T entity)
public virtual T Update(T entity)
public virtual void Delete(T entity)
}
}
SessionManager - singletone for provide access to sessionfactory
public class SessionManager : ISessionFactoryProvider
{
private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private readonly ISessionFactory sessionFactory;
public static ISessionFactory SessionFactory
{
get { return Instance.sessionFactory; }
}
public ISessionFactory GetSessionFactory()
{
return sessionFactory;
}
public static ISession OpenSession()
{
return Instance.GetSessionFactory().OpenSession();
}
public static ISession CurrentSession
{
get
{
if (!CurrentSessionContext.HasBind(Instance.GetSessionFactory()))
return null;
return Instance.GetSessionFactory().GetCurrentSession();
}
}
public static SessionManager Instance
{
get
{
return NestedSessionManager.sessionManager;
}
}
private SessionManager()
{
Log.Info("Start creating factory");
Configuration configuration = new Configuration().Configure();
sessionFactory = configuration.BuildSessionFactory();
Log.Info("End creating factory");
}
class NestedSessionManager
{
internal static readonly SessionManager sessionManager =
new SessionManager();
}
}
NhibernateHelper, which do some work for start and end session:
public static class NHibernateHelper
{
public static void StartSession()
{
var session = SessionManager.SessionFactory.OpenSession();
session.BeginTransaction();
CurrentSessionContext.Bind(session);
}
public static void EndSession()
{
var session = SessionManager.CurrentSession;
CurrentSessionContext.Unbind(SessionManager.SessionFactory);
if (session != null)
{
try
{
if (session.Transaction != null && session.Transaction.IsActive)
session.Transaction.Commit();
}
catch (Exception ex)
{
session.Transaction.Rollback();
throw new ApplicationException("Error committing database transaction. "+ex.Message, ex);
}
finally
{
session.Close();
session.Dispose();
}
}
}
}
May be my design isn't so good, but I couldn't imagine how can I catch this error.
UPD
Sorry my config. I haven't migrate to fluent yet so:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MySQLDialect</property>
<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
<property name="connection.connection_string">***</property>
<property name="show_sql">false</property>
<property name="default_schema">**_***</property>
<property name="current_session_context_class">thread_static</property>
<mapping assembly="***.Core"/>
</session-factory>
</hibernate-configuration>
UPD2
Save method:
public virtual T Save(T entity)
{
NHibernateSession.Save(entity);
return entity;
}
Threadpool callback:
public static void DetectStart(Object threadContext)
{
try
{
var task = (TasksPerAttraction)threadContext;
var startInfo = new ProcessStartInfo(..., ...)
{
UseShellExecute = false,
RedirectStandardOutput = true
};
Process p = Process.Start(startInfo);
var outputXml = p.StandardOutput.ReadToEnd();
p.WaitForExit();
var doc = XDocument.Parse(outputXml);
foreach (var xElement in doc.Root.Descendants("start"))
{
var startDetection = new StartDetection
{
DtStart = DateTime.Parse(xElement.Attribute("startTime").Value),
Attraction = task.Attraction,
};
lock (spinLock)
{
using (var repo = new Repository<StartDetection>(true))
repo.Save(startDetection);
}
}
var tskRepo = new Repository<Task>(true);
foreach(var tsk in task.Tasks)
{
tsk.IsProcessedStart = true;
tskRepo.Update(tsk);
}
tskRepo.Flush();
}
catch (Exception ex)
{
//....
}
}
There are a few potential issues, but I suspect the biggest issue is that you are saving the task.Attraction in one session (so the Attraction for that task is associated to session 1), and then saving the tasks in another session - so you end up with the Attraction in session 1, which is now closed, and session 2 is navigating the relationships to see if it needs to save the Attraction and hence the error. This is a bit of an assumption since I don't have your model or mapping.
I think the easiest fix would be to open the session in your callback, ie:
public static void DetectStart(Object threadContext)
{
try
{
... run your process ...
p.WaitForExit();
// **** OPEN SESSION HERE ****
NHibernateHelper.StartSession();
var doc = XDocument.Parse(outputXml);
foreach (var xElement in doc.Root.Descendants("start"))
{
var startDetection = new StartDetection
{
DtStart = DateTime.Parse(xElement.Attribute("startTime").Value),
Attraction = task.Attraction,
};
lock (spinLock)
{
// *** DON'T CLOSE THE SESSION ON DISPOSE
using (var repo = new Repository<StartDetection>(false))
repo.Save(startDetection);
}
}
// *** DON'T CLOSE THE SESSION ON DISPOSE HERE EITHER!
using(var tskRepo = new Repository<Task>(false))
{
foreach(var tsk in task.Tasks)
{
tsk.IsProcessedStart = true;
tskRepo.Update(tsk);
}
tskRepo.Flush();
}
}
catch (Exception ex)
{
//....
}
finally {
// *** MAKE SURE YOU CLOSE THE SESSION
NHibernateHelper.EndSession();
}
}
Hello Andrew what if you use an IOC to deal with your session? I use ninject and It has been painless also I will share some code that may help you, this is my approximation to solve dealing with Nhibernate, but I am open to suggestions.
The Repo Class:
public class Repositorio<T> : IRepositorio<T> where T : class
{
[Inject]
public ISession Session { get; set; }
#region IRepositorio<T> Members
public IList<T> ListAll()
{
return Session.CreateCriteria<T>().List<T>();
}
public T Look(object id)
{
return Session.Get<T>(id);
}
public void Add(T t)
{
using (ITransaction transaction = Session.BeginTransaction())
{
transaction.Begin();
try
{
Session.Save(t);
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
finally
{
transaction.Dispose();
}
}
}
public void Save(T t)
{
using (ITransaction transaction = Session.BeginTransaction())
{
transaction.Begin();
try
{
Session.SaveOrUpdate(t);
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
finally
{
transaction.Dispose();
}
}
}
public void Delete(T t)
{
using (ITransaction transaction = Session.BeginTransaction())
{
transaction.Begin();
try
{
Session.Delete(t);
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
Console.WriteLine(e.StackTrace);
}
finally
{
transaction.Dispose();
}
}
}
#endregion
}
My Nhibernate Helper:
public sealed class NHibernateHelper
{
public static ISessionFactory SessionFactory { get; set; }
private static void OpenSession()
{
var configuration = new Configuration();
configuration.Configure();
SessionFactory = configuration.BuildSessionFactory();
}
public static ISession GetCurrentSession()
{
if (SessionFactory == null)
{
OpenSession();
}
if (SessionFactory != null)
return SessionFactory.OpenSession();
return null;
}
public static IStatelessSession GetStatelessSession()
{
if (SessionFactory == null)
{
OpenSession();
}
if (SessionFactory != null)
return SessionFactory.OpenStatelessSession();
return null;
}
public static void CloseSessionFactory()
{
if (SessionFactory != null)
SessionFactory.Close();
}
}
In my Module I do this:
How do I Bind the session to a repo:
Bind<ISession>().ToMethod(c => NHibernateHelper.GetCurrentSession()).InSingletonScope().OnDeactivation(c => NHibernateHelper.CloseSessionFactory());
Note: check the scope of the bind maybe for you is more appropriated the thread scope
How do I bind the Open session with the repo
Bind<SomeRepoImpl>().ToSelf();
hope that this help, I will be glad to help you.