Spring 4 + Hibernate 4 - jak skonfigurowac poprawnie LAZY

0

Tworze aplikacje wedlug: http://www.journaldev.com/3524/spring-hibernate-integration-example-tutorial-spring-4-hibernate-3-and-hibernate-4

mam problem z dostaniem sie do elementow z listy (oneToMany) poniewaz obiekt jest detached a sesja zamknieta, a nie chce wymuszac LAZY loadingu

moje fragmenty kodu:

private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    public SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }

    @Override
    public void save(A p)
    {
        Session session = this.sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        session.persist(p);
        tx.commit();
        session.close();
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<A> list()
    {
        Session session = this.sessionFactory.openSession();
        List<A> aList= session.createQuery("from A").list();
        session.close();
        return aList;
    }

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver" />
        ...
    </bean>
 
 
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>org.osomething.A</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>
        
    <bean id="aDAO" class="org.something.ADAOImpl">
        <property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
    </bean>

Jak to usprawnic aby nie trzeba bylo dodawac EAGER, a mialbym dostep do elementow z listy (oneToMany) ?

0

Lekcja na dziś: fetch join w zapytaniu HQL. Dodajesz sobie takie cudo w swoim zapytaniu, dla pola które cię interesuje i wtedy, mimo ze jest lazy, pobierze ci to z bazy.

0

dzieki, ale jak...

moj kod

 @SuppressWarnings("unchecked")
    @Transactional
    @Override
    public List<A> list()
    {
        Session session = this.sessionFactory.getCurrentSession();
        List<A> aList= session.createQuery("from A").list();
        return aList;
    }



@Entity
public class A
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @OneToMany(mappedBy = "a")
    private List<AS> ases= new ArrayList<AS>();



Udalo sie (prawie):


  public List<C> list()
    {
        Session session = this.sessionFactory.getCurrentSession();
        List<C> cList= session.createQuery("from C e join fetch e.a.as").list();
       
        
        return cList;
    }

C zawiera relacje oneToOne z A, a A zawiera relacje one to many z AS. Majac obiekt C chce wyciagnac z niego as.

Tylko dlaczego nagle lista cList zawiera dwa elementy jak polecenie List<C> cList= session.createQuery("from C").list(); zwraca tylko jeden ?

http://stackoverflow.com/questions/263850/how-do-you-create-a-distinct-query-in-hql

http://glueclue.blogspot.com/2006/02/hibernate-duplicates-with-join-fetch.html

ok, no to sobie sam odpowiedzialem, ze to takie zachowanie hibernate.

Wszystko ladnie pieknie, ale czy uzycie tego join fetch jest optymalne ?

W takim razie co nam daje lazy loading, jak i tak musimy wszedzie dawac join fetch jak chcemy dostac sie do elementow ze strony many z OneToMany relacji ?

Jedyny plus, to ze gdybym gdzies potrzebowal liste obiektow bez dzieci, to bedzie mniej sciagania z lazy ?

0
  1. Moja rada: używaj Set a nie List chyba że jest to czymś podyktowane. Bo różne cuda na kiju się dzieją jak masz List mapowane jako onetomany
  2. Lazy daje ci dokładnie tyle, że jeśli nie potrzebujesz wszystkich dzieci to ich nie ciągniesz z bazy. Wyobraź sobie na przykład że robisz stronę internetową "wirtualna czytelnia". User wchodzi i dostaje listę książek a jak kliknie książkę to mu się wyświetla jej treść. Niech książka przechowuje Set rozdziałów. Jak zrobisz EAGER to wyświetlenie listy książek pociągnie całą bazę bo wyciągnie treść każej książki, mimo że nie jest to do niczego potrzebne. Z drugiej stony jak wyświetlasz konkretną książkę to może okazać się sensowne wyciągnięcie wszystkich jej rozdziałów na raz, wtedy robisz fetch join.

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