hibernace: LazyInitializationException: nemohl inicializovat server proxy

hlasů
67

Zde je ten, který má mě zmateně. Snažím se realizovat základní spánku DAO strukturu, ale mám potíže.

Zde je důležité, kód:

int startingCount = sfdao.count();
sfdao.create( sf );
SecurityFiling sf2 = sfdao.read( sf.getId() );
sfdao.delete( sf );
int endingCount = sfdao.count();

assertTrue( startingCount == endingCount );
assertTrue( sf.getId().longValue() == sf2.getId().longValue() );
assertTrue( sf.getSfSubmissionType().equals( sf2.getSfSubmissionType() ) );
assertTrue( sf.getSfTransactionNumber().equals( sf2.getSfTransactionNumber() ) );

Selže ve třetím assertTrue, kde se snaží porovnávat hodnotu v SF na odpovídající hodnotu v SF2. Zde je výjimka:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:86)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    at com.freightgate.domain.SecurityFiling_$$_javassist_7.getSfSubmissionType(SecurityFiling_$$_javassist_7.java)
    at com.freightgate.dao.SecurityFilingTest.test(SecurityFilingTest.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
Položena 06/12/2008 v 02:32
zdroj uživatelem
V jiných jazycích...                            


14 odpovědí

hlasů
68

Problém je v tom, že se snaží získat přístup k kolekci v objektu, který je samostatně stojící . Musíte před přístupem kolekci k aktuální relaci znovu připojit objekt. Můžete tak učinit prostřednictvím

session.update(object);

Používání lazy=falsenení dobré řešení, protože jste zahodili funkci Lazy inicializaci režimu spánku. Když lazy=falseje kolekce je načten do paměti současně, že objekt je požadováno. To znamená, že máme-li sbírku s 1000 položkami, že vše bude načten v paměti, i když budeme k nim mají přístup, nebo ne. A to není dobré.

Přečtěte si tento článek , kde se vysvětluje problém, možná řešení a proč je implementována tímto způsobem. Také pochopit Sessions a transakce, musíte přečíst tento jiný článek .

Odpovězeno 03/09/2010 v 13:15
zdroj uživatelem

hlasů
14

To obecně znamená, že vlastnit spánku relace již uzavřen. Můžete to udělat jednu z následujících ji opravit:

  1. podle toho, co objekt vytvoření tohoto problému, použijte HibernateTemplate.initialize(object name)
  2. Používat lazy=falseve svých HBM souborů.
Odpovězeno 06/12/2008 v 15:51
zdroj uživatelem

hlasů
11

Viz můj článek. Měl jsem stejný problém - LazyInitializationException - a tady je odpověď Nakonec jsem přišel s:
http://community.jboss.org/wiki/LazyInitializationExceptionovercome
Nastavení líný = false není odpověď - to může nahrát všechno najednou, a to nemusí být nutně dobré. Příklad:
1 záznam odkazy Tabulka A:
5 záznamy stolní reference B:
25 záznamy C termíny typu tabulka:
125 záznamů tabulky D
...
atd To je jen jedním příkladem toho, co se může pokazit.
--Tim Sabin

Odpovězeno 16/02/2011 v 21:05
zdroj uživatelem

hlasů
7

Pokud používáte hibernace s SPS anotací pak to bude užitečné. Ve třídě služba by měla být seřizovač pro vedoucího subjektu s @PersistenceContext. změnit na @PersistenceContext (typ = PersistenceContextType.EXTENDED). Poté můžete přistupovat k líné majetek v kdekoliv.

Odpovězeno 26/09/2010 v 14:50
zdroj uživatelem

hlasů
4

Pokud používáte Lazy načítání metodu musí být komentovaný s

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) Pro Stateless Session EJB

Odpovězeno 16/08/2010 v 01:17
zdroj uživatelem

hlasů
3

Setkali jsme se tuto chybu také. To, co jsme udělali, jak vyřešit problém je, že jsme přidán líný = false v souboru mapování spánku.

Zdá se, že jsme měli třída A, který je uvnitř relace, který načte další třídu B. Snažíme se přistupovat k datům z třídy B, ale tato třída B je odpojen od relace.

Abychom získali přístup k tomuto třída B, jsme museli specifikovat třídy A je spánku mapování souboru líný = false atributů. Například,

     <many-to-one name="classA" 
                 class="classB"
                 lazy="false">
        <column name="classb_id"
                sql-type="bigint(10)" 
                not-null="true"/>
    </many-to-one>  
Odpovězeno 03/09/2010 v 09:39
zdroj uživatelem

hlasů
2

Zdá se, že jen vaše DAO používáte relaci. Tak nové relace je otevřena zavřete pro každé volání metody DAO. Tak provádění programu lze shrnout takto:

// open a session, get the number of entity and close the session
int startingCount = sfdao.count();

// open a session, create a new entity and close the session
sfdao.create( sf );

// open a session, read an entity and close the session
SecurityFiling sf2 = sfdao.read( sf.getId() );

// open a session, delete an entity and close the session
sfdao.delete( sf );

etc...

Ve výchozím nastavení, shromažďování a sdružování v subjektu, jsou líní: oni jsou načteny z databáze na vyžádání. Tím pádem:

sf.getSfSubmissionType().equals( sf2.getSfSubmissionType() )

hází výjimku, protože požadovat nové načtení z databáze a relace spojené s nakládkou subjektu již bylo uzavřeno.

K dispozici jsou dva přístupy k řešení tohoto problému:

  • vytvořit relaci uzavřený celý náš kód. Tak by to znamenalo změnu obsahu DAO, aby se zabránilo otevření druhé relaci

  • Vytvoření relace aktualizovat (tj reconnect) svůj subjekt k této relaci před tvrzení.

    session.update (objekt);

Odpovězeno 03/05/2012 v 12:39
zdroj uživatelem

hlasů
2

Pokud víte o dopadu lazy=falsea přesto chcete to dělá jako výchozí (například pro účely prototypování), můžete použít některou z následujících možností:

  • Pokud používáte konfiguraci XML: přidat default-lazy="false"k oblíbeným <hibernate-mapping>prvkem
  • Pokud používáte konfiguraci Anotace: přidat @Proxy(lazy=false)do svého subjektu třída (es)
Odpovězeno 04/11/2010 v 03:08
zdroj uživatelem

hlasů
2

Dobře, konečně přišel na to, kde jsem byl nedbalý. Byl jsem pod mylné představě, že bych měl zabalit každé metody DAO v transakci. Hrozného! Jsem se naučil můj lekci. Jsem táhnul celý kód transakce ze všech metod DAO a zřídili transakce výhradně na application / správce vrstvy. To zcela vyřešit všechny mé problémy. Data je správně načten líný, když jsem ji potřebují, zabalili a zavřeli, jakmile mi commit.

Život je značný ... :)

Odpovězeno 08/01/2009 v 00:17
zdroj uživatelem

hlasů
1

Pokud používáte jaro a SPS anotace, nejjednodušší způsob, jak se vyhnout problému s relace v líné initialize je replaysing:

@PersistenceContext   

na

@PersistenceContext(type = PersistenceContextType.EXTENDED)
Odpovězeno 19/06/2015 v 11:56
zdroj uživatelem

hlasů
1

použijte Hibernate.initialize pro líné pole

Odpovězeno 03/08/2011 v 15:15
zdroj uživatelem

hlasů
1

Myslím, že Piko znamená ve své odpovědi, že existuje soubor HBM. Mám soubor s názvem Tax.java. Informace o mapování jsou uloženy v HBM (= spánku mapování) soubor. Ve třídě tagu je vlastnost s názvem líná . Nastavit tuto vlastnost na hodnotu true. Následující HBM příklad ukazuje způsob, jak nastavit líný vlastnost na hodnotu false .

`Id ...‘

Pokud používáte anotace místo podívat do hibernace documenation. http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/

Doufám, že to pomohlo.

Odpovězeno 26/07/2010 v 14:07
zdroj uživatelem

hlasů
1

Pokud jste ručně řízení relace spánku, možná budete chtít podívat do sessionFactory.getCurrentSession () a souvisejících dokumentů se zde:

http://www.hibernate.org/hib_docs/v3/reference/en/html/architecture-current-session.html

Odpovězeno 09/12/2008 v 03:17
zdroj uživatelem

hlasů
0

Ve výchozím nastavení všechny one-to-manyi many-to-manyasociace jsou přitažené za vlasy líně při které dochází k přístupu poprvé.

Ve vašem use case, můžete překonat tento problém tím, že balí všechny operace DAO do jedné logické transakce:

transactionTemplate.execute(new TransactionCallback<Void>() {
    @Override
    public Void doInTransaction(TransactionStatus transactionStatus) {

        int startingCount = sfdao.count();

        sfdao.create( sf );

        SecurityFiling sf2 = sfdao.read( sf.getId() );

        sfdao.delete( sf );

        int endingCount = sfdao.count();

        assertTrue( startingCount == endingCount );
        assertTrue( sf.getId().longValue() == sf2.getId().longValue() );
        assertTrue( sf.getSfSubmissionType().equals( sf2.getSfSubmissionType() ) );
        assertTrue( sf.getSfTransactionNumber().equals( sf2.getSfTransactionNumber() ) );

        return null;
    }
});

Další možností je načíst všechny Lazy sdružení při načítání subjekt, aby:

SecurityFiling sf2 = sfdao.read( sf.getId() );

by měl načíst líné submissionTypepříliš:

select sf
from SecurityFiling sf
left join fetch.sf.submissionType

Tímto způsobem můžete dychtivě načíst všechny líné vlastnosti a můžete k nim přistupovat po zasedání dostane příliš zavřená.

Můžete vyzvednout tolik [one|many]-to-onesdružení a jeden „[jeden | mnozí] -to-many“ Seznam sdružení (protože běží kartézský součin).

Inicializovat multiple "[jeden | mnozí] -to-many", měli byste použít Hibernate.initialize (úhrady) , hned po načtení root entitu.

Odpovězeno 12/03/2015 v 07:36
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more