NHibernate: Como obter uma instância de entidade do cache da sessão?
Inicio a sessão no início da unidade de trabalho e fecho no final da mesma. A unidade de trabalho é dividida em vários métodos.
Em um método, eu carrego a entidade usandoGet
método. Portanto, isso fica no cache da sessão. A instância da entidade é local para o método Portanto, quando o escopo do método termina, a instância da entidade não está acessível. Mas a entidade ainda está no cache da sessão.
Agora, o segundo método cria uma nova instância da entidade e tenta excluí-la. Isso jogaNonUniqueObjectException
como esperado.
A seguir está a solução que eu posso imaginar, mas não capaz de implementar:
public void Delete<T>(T instance) where T : BaseEntity
{
try
{
nhSession.Delete(instance);
}
catch(NonUniqueObjectException)
{
T instanceFromCache = GetInstanceFromCache<T>(instance);
nhSession.Evict(instanceFromCache);
nhSession.Delete(instance);
}
}
Se eu conseguir obter a instância da entidade do cache da sessão de alguma forma, possoEvict
e espero que o problema seja resolvido. Mas eu não sou capaz de implementar meu imaginárioGetInstanceFromCache
método.
Eu tentei usarnhSession.Get
, mas isso não é útil no meu cenário. O nome da coluna da chave primária no meu banco de dados NÃO é "id" e também não é o mesmo nas tabelas. Em uma tabela, é "Campo1" e em outra é "Campo2". Então não posso usar algo comonhSession.Get(instance.Id)
. MinhasDelete<T>(T instance)
O método recebe uma instância da entidade para excluir como parâmetro. Ele não recebe o valor da chave primária a ser excluída.
Para mais informações, consulte o meude outros Pergunta, questão. Essa pergunta discute o problema UPDATE e como o corrigi; mas o cenário é semelhante.
Editar 1Responder por "@Ricardo Peres" não funciona como está, mas modifiquei um pouco o código dele.
public static TEntity GetInstanceFromCache<TEntity>(this ISession nhSession, object instance) where TEntity : BaseEntity
{
var sessionImpl = nhSession.GetSessionImplementation();
foreach(BaseEntity baseEntity in sessionImpl.PersistenceContext.EntityEntries.Keys)
{
if(baseEntity is TEntity)
{
TEntity instanceFromCache = (TEntity)baseEntity;
if(nhSession.GetIdentifier(instanceFromCache) == nhSession.GetIdentifier(instance))
return baseEntity as TEntity;
}
}
return null;
}
A chamadanhSession.GetIdentifier(instance)
lança uma exceçãoTransientObjectException
("A instância não foi associada a esta sessão"), o que é esperado. Isto é porqueinstance
é desconhecido paranhSession
. Alguma maneira de obter o identificador da entidade que NÃO está associada à sessão?