작업 단위의 시작 부분에서 세션을 시작하고 세션의 끝에서 닫습니다. 작업 단위는 여러 가지 방법으로 작성됩니다.NHibernate : 세션 캐시에서 엔티티 인스턴스를 얻는 방법?
한 가지 방법으로 Get
메서드를 사용하여 엔티티를로드합니다. 그래서 이것은 세션 캐시에 있습니다. Entity 인스턴스는 메서드에 대해 로컬입니다. 따라서 메소드 범위가 끝나면 엔티티 인스턴스에 액세스 할 수 없습니다. 그러나 엔터티는 여전히 세션 캐시에 있습니다.
이제 두 번째 방법은 엔티티의 새 인스턴스를 만들고 삭제하려고 시도합니다. 예상대로 NonUniqueObjectException
이 throw됩니다.
에 따라 내가 상상할 수있는 솔루션이지만, 구현할 수 없습니다 : 어떻게 든 세션 캐시에서 개체 인스턴스를 얻을 수 있다면, 나는 그것을 Evict
수 잘하면 문제가 해결됩니다
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);
}
}
. 그러나 나는 가상의 GetInstanceFromCache
메서드를 구현할 수 없습니다.
nhSession.Get
을 사용해 보았지만, 내 시나리오에서는 도움이되지 않습니다. 내 데이터베이스의 기본 키 열 이름은 "id"가 아니며 테이블간에 동일하지 않습니다. 한 테이블에서 "Field1"이고 다른 테이블에서는 "Field2"입니다. 그래서 nhSession.Get(instance.Id)
과 같은 것을 사용할 수 없습니다. 내 Delete<T>(T instance)
메서드는 매개 변수로 삭제할 엔터티 인스턴스를받습니다. 삭제할 기본 키의 값을받지 못합니다.
자세한 내용은 other 질문을 참조하십시오. 이 질문은 UPDATE 문제와 그 문제점에 대해 논의합니다. 그러나 시나리오는 유사합니다. "@Ricardo 페레스"에 의해
편집 한
대답은 그대로 작동하지 않습니다,하지만 난 그의 코드를 조금 수정했습니다.
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;
}
호 nhSession.GetIdentifier(instance)
예상되는 예외를 TransientObjectException
("인스턴스가이 세션에 관련되지 않은") 발생. nhSession
에 instance
을 알 수 없기 때문입니다. 세션과 관련이없는 엔티티의 식별자를 가져 오는 방법은 무엇입니까?
프록시가있는 경우 : http://stackoverflow.com/a/10328489/1486443. – Najera