HibernateException: U hibernaciji nije vezana niti nit u hibernacijskoj sesiji

Vrh postojanosti

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. Uvod

U ovom kratkom vodiču, pojasnit ćemo kada se izbaci iznimka "Nijedna hibernacijska sesija vezana uz nit" i kako to riješiti.

Ovdje ćemo se usredotočiti na dva različita scenarija:

  1. koristiti LocalSessionFactoryBean
  2. koristiti AnnotationSessionFactoryBean

2. Uzrok

S verzijom 3, Hibernate je predstavio koncept kontekstualne sesije i getCurrentSession () metoda dodana je u SjednicaTvornica razred. Više informacija o kontekstualnoj sesiji možete pronaći ovdje.

Proljeće ima vlastitu implementaciju org.hibernate.context.CurrentSessionContext sučelje - org.springframework.orm.hibernate3.SpringSessionContext (u slučaju Spring Hibernate 3). Ova implementacija zahtijeva da se sesija veže za transakciju.

Naravno, predavanja koja pozivaju getCurrentSession () metoda treba biti označena sa @Transational bilo na razini razreda ili na razini metode. Ako nije, org.hibernate.HibernateException: Nijedna hibernacijska sesija nije vezana uz nit bit će bačen.

Kratko ćemo pogledati primjer.

3. LocalFactorySessionBean

On je prvi scenarij koji bismo gledali u ovom članku.

Definirat ćemo klasu Java Spring konfiguracije s LocalSessionFactoryBean:

@Configuration @EnableTransactionManagement @PropertySource ({"classpath: persistence-h2.properties"}) @ComponentScan ({"com.baeldung.persistence.dao", "com.baeldung.persistence.service"}) javna klasa PersistenceConfigHibernate3 {// ... @Bean public LocalSessionFactoryBean sessionFactory () {LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean (); Konfiguracija resursa = novi ClassPathResource ("exceptionDemo.cfg.xml"); sessionFactory.setDataSource (dataSource ()); sessionFactory.setConfigLocation (config); sessionFactory.setHibernateProperties (hibernateProperties ()); return sessionFactory; } // ...}

Imajte na umu da koristimo Hibernate konfiguracijsku datoteku (iznimkaDemo.cfg.xml) ovdje kako bismo mapirali klasu modela. Ovo je zbog the org.springframework.orm.hibernate3.LocalSessionFactoryBean ne osigurava imovinu paketiToScan, za mapiranje klasa modela.

Evo naše jednostavne usluge:

@Service @Transactional javna klasa EventService {@Autowired private IEventDao dao; javna void kreira (entitet događaja) {dao.create (entitet); }}
@Entity @Table (name = "EVENTS") javna klasa Događaj implementira Serializable {@Id @GeneratedValue private Long id; opis privatnog niza; // ...}

Kao što možemo vidjeti u isječku koda u nastavku, getCurrentSession () metoda SjednicaTvornica klasa koristi se za dobivanje sesije hibernacije:

javna apstraktna klasa AbstractHibernateDao implementira IOperations {private Class clazz; @Autowired private SessionFactory sessionFactory; // ... @Preuzmi javno void stvaranje (T entitet) {Preconditions.checkNotNull (entitet); getCurrentSession (). perzistirati (entitet); } zaštićena sesija getCurrentSession () {povratak sessionFactory.getCurrentSession (); }}

Test u nastavku prolazi, pokazujući kako će se izuzetak izbaciti iz nastave EventService koja sadrži metodu usluge nije označena s @Transational napomena:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (klase = {PersistenceConfigHibernate3.class}, loader = AnnotationConfigContextLoader.class) javna klasa HibernateExceptionScen1MainIntegrationTest {@Autowirered Service Event; @Rule public ExpectedException očekujeEx = ExpectedException.none (); @Test public void whenNoTransBoundToSession_thenException () {očekujeEx.expectCause (IsInstanceOf.instanceOf (HibernateException.class)); očekujeEx.expectMessage ("Nijedna hibernacijska sesija nije vezana za nit," + "i konfiguracija ne dopušta stvaranje" + "ovdje ne-transakcijske"); service.create (novi događaj ("iz LocalSessionFactoryBean")); }}

Ovaj test pokazuje kako se metoda usluge uspješno izvršava kada se EventService razred označen je s @Transational napomena:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (klase = {PersistenceConfigHibernate3.class}, loader = AnnotationConfigContextLoader.class) javna klasa HibernateExceptionScen1MainIntegrationTest {@Autowirered Service Event; @Rule public ExpectedException očekujeEx = ExpectedException.none (); @Test public void whenEntityIsCreated_thenNoExceptions () {service.create (novi događaj ("iz LocalSessionFactoryBean")); Popis događaja = service.findAll (); }}

4. AnnotationSessionFactoryBean

Ova se iznimka može dogoditi i kada koristimo org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean stvoriti SjednicaTvornica u našoj proljetnoj aplikaciji.

Pogledajmo nekoliko primjera koda koji to pokazuju. U toj mjeri definiramo konfiguracijsku klasu Java Spring s AnnotationSessionFactoryBean:

@Configuration @EnableTransactionManagement @PropertySource ({"classpath: persistence-h2.properties"}) @ComponentScan ({"com.baeldung.persistence.dao", "com.baeldung.persistence.service"}) javna klasa PersistenceConfig {// ... @Bean public AnnotationSessionFactoryBean sessionFactory () {AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean (); sessionFactory.setDataSource (dataSource ()); sessionFactory.setPackagesToScan (novi String [] {"com.baeldung.persistence.model"}); sessionFactory.setHibernateProperties (hibernateProperties ()); return sessionFactory; } // ...}

S istim skupom klasa DAO, servisa i modela iz prethodnog odjeljka susrećemo se s iznimkom kako je gore opisano:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = {PersistenceConfig.class}, loader = AnnotationConfigContextLoader.class) javna klasa HibernateExceptionScen2MainIntegrationTest {@Autowired EventService; @Rule public ExpectedException očekujeEx = ExpectedException.none (); @Test public void whenNoTransBoundToSession_thenException () {očekujeEx.expectCause (IsInstanceOf.instanceOf (HibernateException.class)); očekujeEx.expectMessage ("Nijedna hibernacijska sesija nije vezana za nit," + "i konfiguracija ne dopušta stvaranje" + "ovdje ne-transakcijske"); service.create (novi događaj ("iz AnnotationSessionFactoryBean")); }}

Ako klasu usluge označimo s @Transational napomena, metoda usluge radi prema očekivanjima i test prikazan u nastavku prolazi:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = {PersistenceConfig.class}, loader = AnnotationConfigContextLoader.class) javna klasa HibernateExceptionScen2MainIntegrationTest {@Autowired EventService; @Rule public ExpectedException očekujeEx = ExpectedException.none (); @Test public void whenEntityIsCreated_thenNoExceptions () {service.create (novi događaj ("iz AnnotationSessionFactoryBean")); Popis događaja = service.findAll (); }}

5. Rješenje

Jasno je da getCurrentSession () metoda SjednicaTvornica dobiveno od Springa treba pozvati unutar otvorene transakcije. Stoga, rješenje je osigurati da su naše DAO / metode / klase usluga ispravno označene s @Transational bilješka.

Treba napomenuti da je u Hibernate 4 i novijim verzijama poruka o iznimci koja se izbacuje iz istog razloga drugačije sročena. Umjesto „Nijedna hibernacija nije vezana uz nit ”, dobili bismo "Nije moguće dobiti sesiju sinkroniziranu transakcijama za trenutnu nit ”.

Treba istaknuti još jednu važnu točku. Zajedno sa org.hibernate.context.CurrentSessionContext sučelje, Hibernate je predstavio svojstvo hibernate.current_session_context_class koji se može postaviti na klasu koja implementira trenutni kontekst sesije.

Kao što je već rečeno, Spring dolazi s vlastitom implementacijom ovog sučelja: SpringSessionContext. Prema zadanim postavkama postavlja hibernate.current_session_context_class svojstvo jednako ovoj klasi.

Kao posljedicu, ako ovo svojstvo izričito postavimo na nešto drugo, to narušava sposobnost Springa da upravlja sesijom hibernacije i transakcijama. To rezultira i iznimkom, ali se razlikuje od iznimke koja se razmatra.

Rezimirajući, važno je zapamtiti da ne bismo trebali postavljati hibernate.current_session_context_class izričito kada koristimo Spring za upravljanje sesijom hibernacije.

6. Zaključak

U ovom smo članku pogledali zašto a kada iznimka org.hibernate.HibernateException: Nijedna hibernacijska sesija nije vezana uz nit je bačen u Hibernate 3 zajedno s nekim primjerom koda i kako ga možemo lako riješiti.

Kôd za ovaj članak nalazi se na Githubu.

Dno postojanosti

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

$config[zx-auto] not found$config[zx-overlay] not found