1

"Tipo" has one "Profissão:"

@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_profissao", nullable = false)
    public Profissao getProfissao() {
    return profissao;
    }

When I tried to in datatable view data of a relation entities Tipo and Profissao related:

  <p:dataTable var="lista" value="#{tipoBean.tipos}" id="tabelaTipos"
            rows="10" paginator="true" widgetVar="tabelaTipos">

            <p:column headerText="Profissão">
                <h:outputText value="#{lista.profissao.nome}" />


</p:dataTable>

DAO:

 Criteria cri = session.createCriteria(Tipo.class)
                     .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                     .addOrder(Order.asc("nome"));

  return cri.list();

I got this error widely discussed here: org.hibernate.LazyInitializationException: could not initialize proxy - no Session

So I implemented this using "Hibernate.initialize" way.

Criteria cri = session.createCriteria(Tipo.class)
                     .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                     .addOrder(Order.asc("nome"));

            List<Tipo> tipos = (List<Tipo>) cri.list();

            for (Tipo t :tipos) {
                Hibernate.initialize(t.getProfissao()); 

            }

It worked but there's a better solution to it? I don't wanna use Eager solution. Any solutions?

Thanks!

gustavomr
  • 69
  • 2
  • 16
  • 1
    Try using `session.setFetchMode("profissao", FetchMode.JOIN);` and let me know – geoand Aug 11 '14 at 18:21
  • @geoand it worked but using this is not the same as doing relationship like EAGER? When I tried to apply this solution where one item have a many entities related I get this error: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags. – gustavomr Aug 11 '14 at 18:54
  • It's not the same as using eager. It tells hibernate to construct a join query as opposed to using extra queries that eager forces. But yes what you mentioned with the multiple relationships wont work – geoand Aug 11 '14 at 19:13
  • @geoand thanks for your reply! So, I want to know how to do it in the right way. I searched and i'm not getting the right way... – gustavomr Aug 11 '14 at 19:25
  • I've written a basic Hibernate tutorial that you might find helpful. I give you ways to get around the no session/lazy initialisation error. You can find it [here](http://stackoverflow.com/questions/24257449/how-do-i-use-annotations-to-define-x-relationship-in-hibernate-4-and-spring) – JamesENL Aug 12 '14 at 03:47
  • @james-massey I read your tutorial and looks good. But how to avoid this error: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags when using more than one criteria.setFetchMode ? – gustavomr Aug 12 '14 at 10:43
  • Check `OpenSessionInViewFilter` – Kevin Rave Aug 14 '14 at 21:29

1 Answers1

1

First you need to determine what day you need for the page/table. This data needs to be fetched from the db by hibernate somehow, be it by join or separate select or query.

Now you have two options:

  1. Fetch the data in you service layer before returning the object to the view layer. For this you can specify FetchModes (join or select) on your query or use Hibernate.initialize.
  2. Use an open-session in view strategy. With this solution the view can load additional data by traversing the object model. If an association was previously not loaded, but the view invokes the getter, hibernate will initialize the proxy.

Second option Pro: more flexible: if you need more data in the view later on, you don't need to change the service layer. This is because the service layer head no knowledge of what data is used. Con: it is harder to find performance problems: since the view loads data when necessary, the bulk of the data might be loaded after your service layer has done its job. Measuring response times in your service layer can often easily bare accomplished by adding an interceptor. Depending on you view technology, measuring rendering time might be much harder.

Maarten Winkels
  • 2,407
  • 16
  • 15
  • thanks. Using option 1 in fetchmode (join) I got few queries than "Hibernate.initialize" but my problem is where an entitie has to load (join) with more than one entitie I got this error org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags. – gustavomr Aug 12 '14 at 10:42
  • Only one OneToMany association with FetchMode.Join is allowed. If you really need to fetch multiple collections, you'll have to resort to FetchMode.Select for all but one. This will result in n+1 selection problems. – Maarten Winkels Aug 12 '14 at 12:06