1

I have two models: Ordine and DettaglioOrdine. I would like that, when I save an object of type "Ordine", hibernate also save his child "DettaglioOrdine" (and this works). But, if I do a select query, the query is very very slow because hibernate retrieve also DettaglioOrdine. So, I would like the "Ordine" object without "DettaglioOrdine" object.

"Ordine" model:

@Entity
@Table(name="ordini")
@NamedQuery(name="Ordine.findAll", query="SELECT o FROM Ordine o")
public class Ordine extends DataObject<Integer> {
    private static final long serialVersionUID = 1L;
    private Integer id;
[...]
    private List<Dettagliordine> dettagliordine;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    //bi-directional many-to-one association to Dettagliordine
    @Column(insertable = true, updatable = true)
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="ordine")
    public List<Dettagliordine> getDettagliordine() {
        return this.dettagliordine;
    }

    public void setDettagliordine(List<Dettagliordine> dettagliordine) {
        this.dettagliordine = dettagliordine;
    }

    public Dettagliordine addDettagliordine(Dettagliordine dettaglioordine) {
        dettaglioordine.setOrdine(this);
        this.dettagliordine.add(dettaglioordine);

        return dettaglioordine;
    }

    public Dettagliordine removeDettagliordine(Dettagliordine dettagliordine) {
        dettagliordine.setOrdine(null);
        this.dettagliordine.remove(dettagliordine);
        
        return dettagliordine;
    

    }
}

DettaglioOrdine Model:

@Entity
@Table(name="dettagliordine")
@NamedQuery(name="Dettagliordine.findAll", query="SELECT d FROM Dettagliordine d")
public class Dettagliordine extends DataObject<Integer> {
    private static final long serialVersionUID = 1L;
    private Integer id;
    
        [...]
        
    public Dettagliordine() {
    }
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    public Integer getId() {
        return this.id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    [...]
    
    //bi-directional many-to-one association to Ordini
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="idOrdine", nullable=false)
    public Ordine getOrdine() {
        return this.ordine;
    }
    public void setOrdine(Ordine ordine) {
        this.ordine = ordine;
    }
}

And this is my query:

SessionFactory sessionFactory = getSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        List<OrdineDTO> result = null;
        try{
            String hql = "select d.ordine from Dettagliordine d "
                    + "group by d.ordine.id";
            Query<Ordine> query = session.createQuery(hql,Ordine.class);
            List<Ordine> res = query.getResultList();
            result = new OrdineDMO().unmarshall(res);
        }catch (DMOException e) {
            e.printStackTrace();
        }
smanulla
  • 99
  • 3
  • 13

1 Answers1

1

It is not Hibernate. You have fetch=FetchType.LAZY for dettagliordine. Hibernate doesn't have to fetch the lazy association with the parent.

The problem can be here

result = new OrdineDMO().unmarshall(res);

if the code inside unmarshall() method touches dettagliordine or invoke a method, that differs from get, set methods (like toString() method), Hibernate will fetch dettagliordine association.

You can enable Hibernate logging and debug the code. You will see when fetching actually happens. Also keep in mind, if you debug persistent classes, the debugger can cause invoking of toString() method and the association will be fetched too.

Better to move this line outside session/@Transactional block of code.

result = new OrdineDMO().unmarshall(res);

You will have LazyInitializationExcepton, with any unwanted access to lazy associations.

v.ladynev
  • 19,275
  • 8
  • 46
  • 67
  • OMG! You're my hero! In my unmarshall() I have this line: OrdineDTO dto = new ModelMapper().map(data, OrdineDTO.class); and I've just seen that OrdineDTO has List as a property. Now I use another DTO class (without List) and it perfectly works! Thanks a lot! You saved my day! :) – smanulla Apr 11 '22 at 16:14
  • @smanulla Always ready to help! – v.ladynev Apr 12 '22 at 10:30