JSF/Hibernate - begintransaction oraz commit

0

Witam, mam problem i nie wiem dlaczego on występuje, otóż:

Przy takim kodzie:

        try {
            org.hibernate.Transaction tx = session.beginTransaction();
            Query q = session.createQuery("from Actor as actor where actor.actorId in (select filmCat.id.categoryId from FilmCategory as filmCat where filmCat.id.filmId='" + filmId + "')");
            actorList = q.list();
            tx.commit();

        } catch (Exception e) {
            e.printStackTrace();
        }

wyrzuca mi java.lang.NullPointerException i żadnych więcej konkretów - reszta kodu jest na pewno ok, nie będę wklejać. Generalnie try failuje i wywołuje mi e.printStackTrace() z catch'a. Natomiast, gdy usunę begintransaction() oraz commit() czyli pozostawię to w takiej formie:

        try {
            Query q = session.createQuery("from Actor as actor where actor.actorId in (select filmCat.id.categoryId from FilmCategory as filmCat where filmCat.id.filmId='" + filmId + "')");
            actorList = q.list();


        } catch (Exception e) {
            e.printStackTrace();
        }

to wtedy mi to działa. Mam coś nie tak w ustawieniach hibernate ? Proszę o pomoc ;)

BTW, jeżeli działa bez begintransation() oraz commit() to po co one tam są potrzebne ? :D

0

Wyprintuj zmienną tx żeby wykluczyć nulla.

0
Visher napisał(a):

Wyprintuj zmienną tx żeby wykluczyć nulla.

0
Visher napisał(a):

Wyprintuj zmienną tx żeby wykluczyć nulla.

Czyli jak dobrze zrozumiałem Twoje zdanie, to begintransaction oraz commit są tylko po to (a w sumie aż po to) aby sprawdzić czy transkacja przebiegła pomyślnie / czy zapytanie zostało pomyślnie zrealizowane, tak ? A nie można sprawdzić rodzaj obiektu jaki otrzymaliśmy z zapytania np. size() dla listy ?

0
Mikolooo3 napisał(a):
Visher napisał(a):

Wyprintuj zmienną tx żeby wykluczyć nulla.

Czyli jak dobrze zrozumiałem Twoje zdanie, to begintransaction oraz commit są tylko po to (a w sumie aż po to) aby sprawdzić czy transkacja przebiegła pomyślnie / czy zapytanie zostało pomyślnie zrealizowane, tak ? A nie można sprawdzić rodzaj obiektu jaki otrzymaliśmy z zapytania np. size() dla listy ?

Aby weryfikować wykonywane operacje np. sql, ale mi w hibernate nie śmiga...

0
Mikolooo3 napisał(a):
Visher napisał(a):

Wyprintuj zmienną tx żeby wykluczyć nulla.

Czyli jak dobrze zrozumiałem Twoje zdanie, to begintransaction oraz commit są tylko po to (a w sumie aż po to) aby sprawdzić czy transkacja przebiegła pomyślnie / czy zapytanie zostało pomyślnie zrealizowane, tak ? A nie można sprawdzić rodzaj obiektu jaki otrzymaliśmy z zapytania np. size() dla listy ?

Ja tylko napisałem żebyś wyprintował tx, czyli:

System.out.println(tx);

i powiedział nam czy jest null, czy nie..

0
Visher napisał(a):
Mikolooo3 napisał(a):
Visher napisał(a):

Wyprintuj zmienną tx żeby wykluczyć nulla.

Czyli jak dobrze zrozumiałem Twoje zdanie, to begintransaction oraz commit są tylko po to (a w sumie aż po to) aby sprawdzić czy transkacja przebiegła pomyślnie / czy zapytanie zostało pomyślnie zrealizowane, tak ? A nie można sprawdzić rodzaj obiektu jaki otrzymaliśmy z zapytania np. size() dla listy ?

Ja tylko napisałem żebyś wyprintował tx, czyli:

System.out.println(tx);

i powiedział nam czy jest null, czy nie..

To mi wypuło:

org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction@100aac8f.

przy kolejnych wywołaniach (w obrębie tej samej sesji) tx=null, o co chodzi ?

Nie ogarniam czegoś w tych transakcjach hibernate. Gdy wywołuję drugi raz tę samą funkcję z zapytaniem (łącznie z begin oraz commitem) to dostaje error (tutaj tx=null):

org.hibernate.SessionException: Session is closed!
at org.hibernate.internal.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:129)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1393)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
at $Proxy5.beginTransaction(Unknown Source)
at dvdrental.FilmHelper.getFilmTitles(FilmHelper.java:26)
at dvdrental.FilmController.getFilmTitles(FilmController.java:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:87)

lub ten:

at org.hibernate.internal.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:129)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1393)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
at $Proxy5.beginTransaction(Unknown Source)
at dvdrental.FilmHelper.getFilmTitles(FilmHelper.java:26)
at dvdrental.FilmController.getFilmTitles(FilmController.java:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:87)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIData.getValue(UIData.java:731)
at javax.faces.component.UIData.getDataModel(UIData.java:1798)
at javax.faces.component.UIData.setRowIndexWithoutRowStatePreserved(UIData.java:484)
at javax.faces.component.UIData.setRowIndex(UIData.java:473)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:81)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:820)
at javax.faces.component.UIData.encodeBegin(UIData.java:1118)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1755)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

O co z tym chodzi ?

0

@Visher, @Shalom

Wiecie co panowie, chyba coś mi się mocno pokiełbasiło, bo już sam nie wiem co o tym myśleć, ale chyba myliłem 2 pojęcia sesji - sesje użytkownika na serwerze oraz oddzielną sesję dla hibernate dla połączeń z bazą danych. Czy to w tym przypadku są dwa oddzielne przypadki ?

Dotychczas miałem tworzoną jedną sesje tylko na początku za pomocą tego kodu:

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;

/**
 * Hibernate Utility class with a convenient method to get Session Factory
 * object.
 *
 * @author nb
 */
public class HibernateUtil {

    private static final SessionFactory sessionFactory;
    
    static {
        try {
            // Create the SessionFactory from standard (hibernate.cfg.xml) 
            // config file.
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Log the exception. 
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

Tworzyłem 1 obiekt powyższej klasy i korzystałem z niego w całej aplikacji.
Czy to stąd wynikają moje problemy z begintransaction oraz commitem ?

Proszę o naprostowanie, bo pogubiłem się mocno ;)

0

@Shalom

A jak to się ma z zamykaniem i otwieraniem pojedynczych sesji ?

        HibernateUtil.getSessionFactory().openSession();
        Transaction tx = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
        // zapytanie HQL
        tx.commit();
        HibernateUtil.getSessionFactory().close();

W taki sposób mam to teraz robić ?

Wyczytałem, że podobno przy tworzeniu obiektu SessionFactory jest automatycznie otwierana sesja i trzeba ją pobrać za pomocą getCurrentSession(), jeżeli tak to jak to się ma do powyższego kodu, czy będzie kolidować ?

0

@Shalom

Jeszcze jedno, jaki jest czas trawania obiektu sesji pobieranego za pomocą:

HibernateUtil.getSessionFactory().getCurrentSession()

Zauważyłem, że nie mogę zamykać takiej sesji za pomocą metody close(), dlaczego ?

Tzn nie mogę zrobić czegoś takiego:

try {
        	this.session = HibernateUtil.getSessionFactory().getCurrentSession();
        	this.tx = session.beginTransaction();
//hql query tutaj
this.tx.commit();
} catch(Exception e) {
} finally {
session.close();
}

mam ustawione

<property name="hibernate.current_session_context_class">thread</property>

0

@Shalom

Znalazłem częściowe rozwiązanie tutaj:

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/tutorial.html#tutorial-firstapp-workingpersistence w podpunkcie "1.1.7. Loading and storing objects"

jednakże tam jest dodatkowo napisane, że "sesji nie należy używać do pojedynczych operacji". No ale skoro mam 1 metodę dla konkretnej operacji np. metodę do pobrania pracowników z tabeli to jak inaczej mam nie używać "1 sesji dla 1 operacji". Mógłby mi ktoś to wytłumaczyć ? Dzięki.

0

Chodzi o to że otwieranie i zamykanie sesji jest kosztowne i robienie tego dla każdego zapytania generuje ci bardzo duży narzut. Mógłbyś przechowywać sobie sesje hibernatową w managed beanie z session scope i z niego korzystać. Wtedy będziesz miał jedna sesję per użytkownika.

0
Shalom napisał(a):

Chodzi o to że otwieranie i zamykanie sesji jest kosztowne i robienie tego dla każdego zapytania generuje ci bardzo duży narzut. Mógłbyś przechowywać sobie sesje hibernatową w managed beanie z session scope i z niego korzystać. Wtedy będziesz miał jedna sesję per użytkownika.

A jak taki wpis dla "sesji hibernate" miałby wyglądać ?

Dla normalnych beanów mam wpisy pod ten szablon:

<managed-bean> <managed-bean-name>bname</managed-bean-name> <managed-bean-class>pkg.NazwaKlasy</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean>

Jak to wyglądałoby w przypadku opisywanym przez ciebie i jak wtedy się do tego odwoływać ?

0

Sama deklaracja beana byłaby taka sama zasadniczo (BTW wiesz że od lat da się to robić adnotacjami?), tylko przy tworzeniu beana musiałbyś sobie pobrać do pola tego beana sesje hibernate z session factory.

1 użytkowników online, w tym zalogowanych: 0, gości: 1