czy każdy może podać/polecić właściwą klasę pomocniczą typu OO do zarządzania pojedynczą sesją SessionFactory, a także do zarządzania sesjami?NHibernate - dobra, kompletna działająca klasa pomocnicza do zarządzania SessionFactory/Session
Odpowiedz
Jasne, to co kiedyś, kiedy zaczynasz z NHibernate:
Session Fabryka
public class BaseDataAccess
{
protected ISession m_session;
public BaseDataAccess()
{
m_session=NHibernateHttpModule.CurrentSession;
}
public static ISession OpenSession()
{
Configuration config;
ISessionFactory factory;
ISession session;
config = new Configuration();
if (config==null)
{
throw new InvalidOperationException("NHibernate configuration is null.");
}
config.AddAssembly("My.Assembly.Here");
factory = config.BuildSessionFactory();
if (factory==null)
{
throw new InvalidOperationException("Call to Configuration.BuildSessionFactory() returned null.");
}
session = factory.OpenSession();
if (session==null)
{
throw new InvalidOperationException("Call to factory.OpenSession() returned null.");
}
return session;
}
}
Daj mi znać, jeśli to pomaga.
Dziękujemy! Jest to pomocne, ale szukam czegoś, co jest bardziej wytrzymałe.
Na przykład, na stronie NH (http://hibernate.org/363.html#A9) znajduje się artykuł autorstwa Andrew Mayorova, który publikuje trzy pliki, takie jak ten (http://nhibernate.sourceforge.net/contrib/Wiki_AndrewMayorovAspNet.zip).
Chodzi o to, że nie przynosi to zbytniej pomocy. Nie jestem do końca pewny, jak go właściwie wykorzystać. Próbowałem niektórych rzeczy, ale wpadłem w kłopoty.
Ktoś ma coś, co używa tego lub podobnego?
Zapoznaj się z Billy McCafferty's work. Jego wcześniejsza wersja miała pewne ograniczenia, musisz poprawić obsługę błędów związanych z zamykaniem i płukaniem i nie jestem pewien, czy mam rację, ale opowiem, jak zmodyfikowałem jego rzeczy.
Billy pracuje również nad nowym środowiskiem, które używa MVC & nHilbernate o nazwie S #arp Architechure, którego aktualnie używam, i do tej pory tak dobrze.
W każdym razie oto moja zmodyfikowana wersja jego kodu. Nie robię żadnych gwarancji dokładności ani kompletności i korzystasz z nich na własne ryzyko. Jeśli używasz tego, upewnij się, że zamknąłeś sesję. Jeśli masz jakieś pytania, wyślij mi e-mail [joshua] [dot] [berke] w [gmail ... znasz resztę].
/// <summary>
/// Handles creation and management of sessions and transactions. It is a singleton because
/// building the initial session factory is very expensive. Inspiration for this class came
/// from Chapter 8 of Hibernate in Action by Bauer and King. Although it is a sealed singleton
/// you can use TypeMock (http://www.typemock.com) for more flexible testing.
/// </summary>
public sealed class NHibernateSessionManager
{
private const string DefaultConfigFile = "DefaultAppWeb.Config";
private static readonly object _syncRoot = new object();
#region Thread-safe, lazy Singleton
/// <summary>
/// This is a thread-safe, lazy singleton. See http://www.yoda.arachsys.com/csharp/singleton.html
/// for more details about its implementation.
/// </summary>
public static NHibernateSessionManager Instance
{
get
{
return Nested.NHibernateSessionManager;
}
}
/// <summary>
/// Private constructor to enforce singleton
/// </summary>
private NHibernateSessionManager() { }
/// <summary>
/// Assists with ensuring thread-safe, lazy singleton
/// </summary>
private class Nested
{
static Nested() { }
internal static readonly NHibernateSessionManager NHibernateSessionManager =
new NHibernateSessionManager();
}
#endregion
/// <summary>
/// This method attempts to find a session factory stored in <see cref="sessionFactories" />
/// via its name; if it can't be found it creates a new one and adds it the hashtable.
/// </summary>
/// <param name="sessionFactoryConfigPath">Path location of the factory config</param>
private ISessionFactory GetSessionFactoryFor(string sessionFactoryConfigPath)
{
Check.Require(!string.IsNullOrEmpty(sessionFactoryConfigPath),
"sessionFactoryConfigPath may not be null nor empty");
// Attempt to retrieve a stored SessionFactory from the hashtable.
ISessionFactory sessionFactory;// = (ISessionFactory)sessionFactories[sessionFactoryConfigPath];
// try and get a session factory if we don't find one create it
lock (_syncRoot)
{
if (!sessionFactories.TryGetValue(sessionFactoryConfigPath, out sessionFactory))
{
Configuration cfg = new Configuration();
if (sessionFactoryConfigPath != DefaultConfigFile)
{
Check.Require(File.Exists(sessionFactoryConfigPath),
"The config file at '" + sessionFactoryConfigPath + "' could not be found");
cfg.Configure(sessionFactoryConfigPath);
}
else
{
cfg.Configure();
}
// Now that we have our Configuration object, create a new SessionFactory
sessionFactory = cfg.BuildSessionFactory();
Check.Ensure(sessionFactory != null, "sessionFactory is null and was not built");
sessionFactories.Add(sessionFactoryConfigPath, sessionFactory);
}
}
return sessionFactory;
}
/// <summary>
/// Allows you to register an interceptor on a new session. This may not be called if there is already
/// an open session attached to the HttpContext. If you have an interceptor to be used, modify
/// the HttpModule to call this before calling BeginTransaction().
/// </summary>
public void RegisterInterceptorOn(string sessionFactoryConfigPath, IInterceptor interceptor)
{
ISession session = (ISession)ContextSessions[sessionFactoryConfigPath];
if (session != null && session.IsOpen)
{
throw new CacheException("You cannot register an interceptor once a session has already been opened");
}
GetSessionFrom(sessionFactoryConfigPath, interceptor);
}
public ISession GetSessionFrom(string sessionFactoryConfigPath)
{
return GetSessionFrom(sessionFactoryConfigPath, null);
}
/// <summary>
/// Gets or creates an ISession using the web/app config file.
/// </summary>
/// <returns></returns>
public ISession GetSessionFrom()
{
return GetSessionFrom(DefaultConfigFile, null);
}
/// <summary>
/// Gets a session with or without an interceptor. This method is not called directly; instead,
/// it gets invoked from other public methods.
/// </summary>
private ISession GetSessionFrom(string sessionFactoryConfigPath, IInterceptor interceptor)
{
var allSessions = ContextSessions;
ISession session = null;
if (!allSessions.TryGetValue(sessionFactoryConfigPath, out session))
{
if (interceptor != null)
{
session = GetSessionFactoryFor(sessionFactoryConfigPath).OpenSession(interceptor);
}
else
{
session = GetSessionFactoryFor(sessionFactoryConfigPath).OpenSession();
}
allSessions[sessionFactoryConfigPath] = session;
}
//session.FlushMode = FlushMode.Always;
Check.Ensure(session != null, "session was null");
return session;
}
/// <summary>
/// Flushes anything left in the session and closes the connection.
/// </summary>
public void CloseSessionOn(string sessionFactoryConfigPath)
{
ISession session;
if (ContextSessions.TryGetValue(sessionFactoryConfigPath, out session))
{
if (session.IsOpen)
{
session.Flush();
session.Close();
}
ContextSessions.Remove(sessionFactoryConfigPath);
}
}
public ITransaction BeginTransactionOn(string sessionFactoryConfigPath)
{
ITransaction transaction;
if (!ContextTransactions.TryGetValue(sessionFactoryConfigPath, out transaction))
{
transaction = GetSessionFrom(sessionFactoryConfigPath).BeginTransaction();
ContextTransactions.Add(sessionFactoryConfigPath, transaction);
}
return transaction;
}
public void CommitTransactionOn(string sessionFactoryConfigPath)
{
try
{
if (HasOpenTransactionOn(sessionFactoryConfigPath))
{
ITransaction transaction = (ITransaction)ContextTransactions[sessionFactoryConfigPath];
transaction.Commit();
ContextTransactions.Remove(sessionFactoryConfigPath);
}
}
catch (HibernateException he)
{
try
{
RollbackTransactionOn(sessionFactoryConfigPath);
}
finally
{
throw he;
}
}
}
public bool HasOpenTransactionOn(string sessionFactoryConfigPath)
{
ITransaction transaction;
if (ContextTransactions.TryGetValue(sessionFactoryConfigPath, out transaction))
{
return !transaction.WasCommitted && !transaction.WasRolledBack;
}
return false;
}
public void RollbackTransactionOn(string sessionFactoryConfigPath)
{
try
{
if (HasOpenTransactionOn(sessionFactoryConfigPath))
{
ITransaction transaction = (ITransaction)ContextTransactions[sessionFactoryConfigPath];
transaction.Rollback();
}
ContextTransactions.Remove(sessionFactoryConfigPath);
}
finally
{
ForceCloseSessionOn(sessionFactoryConfigPath);
}
}
/// <summary>
/// Since multiple databases may be in use, there may be one transaction per database
/// persisted at any one time. The easiest way to store them is via a hashtable
/// with the key being tied to session factory. If within a web context, this uses
/// <see cref="HttpContext" /> instead of the WinForms specific <see cref="CallContext" />.
/// Discussion concerning this found at http://forum.springframework.net/showthread.php?t=572
/// </summary>
private Dictionary<string, ITransaction> ContextTransactions
{
get
{
if (IsInWebContext())
{
if (HttpContext.Current.Items[TRANSACTION_KEY] == null)
HttpContext.Current.Items[TRANSACTION_KEY] = new Dictionary<string, ITransaction>();
return (Dictionary<string, ITransaction>)HttpContext.Current.Items[TRANSACTION_KEY];
}
else
{
if (CallContext.GetData(TRANSACTION_KEY) == null)
CallContext.SetData(TRANSACTION_KEY, new Dictionary<string, ITransaction>());
return (Dictionary<string, ITransaction>)CallContext.GetData(TRANSACTION_KEY);
}
}
}
/// <summary>
/// Since multiple databases may be in use, there may be one session per database
/// persisted at any one time. The easiest way to store them is via a hashtable
/// with the key being tied to session factory. If within a web context, this uses
/// <see cref="HttpContext" /> instead of the WinForms specific <see cref="CallContext" />.
/// Discussion concerning this found at http://forum.springframework.net/showthread.php?t=572
/// </summary>
private Dictionary<string, ISession> ContextSessions
{
get
{
if (IsInWebContext())
{
if (HttpContext.Current.Items[SESSION_KEY] == null)
HttpContext.Current.Items[SESSION_KEY] = new Dictionary<string, ISession>();
return (Dictionary<string, ISession>)HttpContext.Current.Items[SESSION_KEY];
}
else
{
if (CallContext.GetData(SESSION_KEY) == null)
CallContext.SetData(SESSION_KEY, new Dictionary<string, ISession>());
return (Dictionary<string, ISession>)CallContext.GetData(SESSION_KEY);
}
}
}
private bool IsInWebContext()
{
return HttpContext.Current != null;
}
private Dictionary<string, ISessionFactory> sessionFactories = new Dictionary<string, ISessionFactory>();
private const string TRANSACTION_KEY = "CONTEXT_TRANSACTIONS";
private const string SESSION_KEY = "CONTEXT_SESSIONS";
public bool HasOpenTransactionOn()
{
return HasOpenTransactionOn(DefaultConfigFile);
}
public void CommitTransactionOn()
{
CommitTransactionOn(DefaultConfigFile);
}
public void CloseSessionOn()
{
CloseSessionOn(DefaultConfigFile);
}
public void ForceCloseSessionOn()
{
ForceCloseSessionOn(DefaultConfigFile);
}
public void ForceCloseSessionOn(string sessionFactoryConfigPath)
{
ISession session;
if (ContextSessions.TryGetValue(sessionFactoryConfigPath, out session))
{
if (session.IsOpen)
{
session.Close();
}
ContextSessions.Remove(sessionFactoryConfigPath);
}
}
public void BeginTransactionOn()
{
this.BeginTransactionOn(DefaultConfigFile);
}
public void RollbackTransactionOn()
{
this.RollbackTransactionOn(DefaultConfigFile);
}
}
Dobre rzeczy. Używając NH 3.2, działa świetnie z jednym modem: musiałem zmienić 'HasOpenTransactionOn' by użyć' transaction.IsActive'. [Oto dlaczego] (http://stackoverflow.com/a/1007633/612265). –
Ohh nice! Dzięki wielkie – JoshBerke
I polecam sprawdzić Rhino Commons bibliotekę Ayende „s. Model documentation jest w tej chwili nieco niewystarczający, ale gdy już się uruchomisz, praca z NHibernate będzie DUŻO łatwiejsza.
W przeszłości odniosłem wielki sukces, korzystając z modułów wsparcia NHibernate Spring.NET. Zobacz http://www.springframework.net/downloads/Spring.Data.NHibernate/. Powinieneś być w stanie użyć modułu OpenSessionInView i wydłużyć swoje DAO z DAibernateSupport DAO, aby uzyskać pełną obsługę zarządzania open session in view pattern. Dodatkowo, mimo że nigdy tego nie próbowałem, powinieneś być w stanie użyć powyższych ram, nawet jeśli zrezygnujesz z resetowania ofert Spring.NET (mianowicie IoC i AOP).
Napisałem numer blog post w tym miejscu, w którym korzystam z implementacji zarządzanej sieci w kontekście obsługi sesji kontekstowych. Może tego właśnie szukasz?
NHibernate Burrow wygląda obiecująco. Właśnie zacząłem go używać i nie mam żadnych problemów do tej pory.
dwie propozycje:
- Jeffrey Palermo HybridSessionBuilder (jeffreypalermo.com/blog/use-this-nhibernate-wrapper-to-keep-your-repository-classes-simple)
- Zobacz przykłady kodu (konkretnie zobaczyć Sesja 13) w lecie NHibernate (www.summerofnhibernate.com)
może chcesz rozważyć swoją DAL mniej dotyczy zarządzania sesjami NHibernate wykorzystując NHibernate.Burrow (lub realizuje podobny wzór samemu).
"NHibernate.Burrow to lekkie oprogramowanie pośredniczące opracowane w celu obsługi aplikacji .Net przy użyciu NHibernate, zapewniając zaawansowane i inteligentne zarządzanie sesjami/transakcjami oraz inne ułatwienia."
Jeśli zdecydujesz się toczyć własne istnieją pewne użyteczne linki na dole tej strony:
Użyteczna wyszukiwarka google termin będzie „NHibernate Session Management” i „Sesje z kontekstu” ...
Nie brakuje pomysłów - można powiedzieć, że jest ich zbyt wiele, mam nadzieję, że opinia zacznie ciążyć wokół Nory lub czegoś podobnego ...
- 1. klasa aktywna nie działająca na stronie
- 2. Doradztwo w zakresie zarządzania sesjami NHibernate
- 3. Narzędzie do zarządzania migracją NHibernate, takie jak EntityFramework, Django-South
- 4. Dobra klasa asertywna do użytku produkcyjnego? Odpowiednik Java PowerAssert Groovy?
- 5. NHibernate: Jedna klasa bazowa, kilka mapowań
- 6. Do czego służy funkcja pomocnicza Html.AntiForgeryToken?
- 7. Kompletna ścieżka do pliku Xcode 4
- 8. czas pozostały do opłat jest kompletna, iOS
- 9. Dobra praktyka do wielowątkowości
- 10. Projektowanie dziedziczenia przy użyciu interfejsu + klasa abstrakcyjna. Dobra praktyka?
- 11. JSON.NET: JsonCreationConverter działająca implementacja WriteJson
- 12. Biblioteka pomocnicza Gradle i Android
- 13. Emacs: Kompletna metoda klasy podstawowej dla Pythona
- 14. Kompletna, wydajna implementacja modułu NumericLiteral
- 15. Aplikacja działająca w tle
- 16. Działająca kapibara z nginxem
- 17. Jak sprawdzić, czy Java Future jest kompletna?
- 18. Narzędzie GUI do zarządzania HBase
- 19. Narzędzie do zarządzania adresami URL?
- 20. Java Framework do zarządzania zadaniami
- 21. Rozwiązanie do zarządzania tożsamością/SSO?
- 22. GUI do zarządzania filtrami Gmaila?
- 23. Linq do NHibernate
- 24. Java działająca jako usługa Unix
- 25. Typowe wzorce zarządzania pamięcią
- 26. Działająca kolejność Z dla UIImageView
- 27. działająca konsola Rails w produkcji
- 28. Hasło chroniące przed meteorami kompletna aplikacja
- 29. Tabulacja kompletna od: otwarta w Macvim?
- 30. Dlaczego warto używać Singleton do zarządzania połączeniem db?
Co masz na myśli mówiąc "solidne"? Czy możesz bardziej precyzyjnie określić, czego brakuje? Co próbowałeś? I jakie kłopoty napotkaliście? Walczyłem, kiedy zaczynałem od NHibernate, więc chciałbym pomóc, jeśli to w ogóle możliwe. –