1

I am pretty new in JPA and Hibernate and I have the following problem.

Into a Spring MVC project I have this Tid001Anagpartecipa model class that map the fields on the TID001_ANAGPARTECIPA table defined on the database:

@Entity
@Table(name="TID001_ANAGPARTECIPA")
@NamedQuery(name="Tid001Anagpartecipa.findAll", query="SELECT t FROM Tid001Anagpartecipa t")
public class Tid001Anagpartecipa implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="PRG_PAR")
    private Integer prgPar;

    ................................................................
    ................................................................
    ................................................................

    @Lob @Basic(fetch=FetchType.LAZY)
    @Column(name="OGG_DOC_ALL")
    private byte[] oggDocAll;


    @Lob @Basic(fetch=FetchType.LAZY)
    @Column(name="OGG_DOC_DEL_ALL")
    private byte[] oggDocDelAll;

    ................................................................
    ................................................................
    GETTER & SETTER METHODS
    ................................................................
    ................................................................
}

As you can see on this table there are 2 BLOB fields annoted with the @Lob annotation, these fields contain 2 files stored on the DB.

In this class is also declared this named query that retrieve all the Tid001Anagpartecipa object stored as record of the TID001_ANAGPARTECIPA table:

As you can see in the previous code snipper the @Lob fields it used the lazy strategy (by @Basic(fetch=FetchType.LAZY)). So I expected that when I retrieve a Tid001Anagpartecipa object these 2 @Lob fields are not initizialized.

Into a controller method I perform this operation that retrieve the Tid001Anagpartecipa object:

Tid001Anagpartecipa anagrafica = getAnagraficaPartecipante(model);
List<Tid002Candidatura> listaCandidatureDB = anagrafica.getTid002Candidaturas();

The object is correctly retrieve but the problem is that the previous 2 @Lob fields are inizialized and I want that these fields are not inizialized (infact I used the @Basic(fetch=FetchType.LAZY) directive).

Why are these fields retrieved? What am I missing? How can I say to Hibernate to not retrieve these @Lob fields when the Tid001Anagpartecipa is retrieved?

Tnx

AndreaNobili
  • 34,200
  • 85
  • 240
  • 456

2 Answers2

1

Section 11.1.6 of the JPA spec notes with regard to the @Basic annotation:

The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed. The implementation is permitted to eagerly fetch data for which the LAZY strategy hint has been specified.

Hibernate does support lazy loading of simple properties but requires byte code enhancement to do so:

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-fetching-lazyproperties

And without this:

If your persistent classes are not enhanced, Hibernate will ignore lazy property settings and return to immediate fetching.

Alan Hay
  • 20,941
  • 2
  • 47
  • 97
  • Nothing. You need to change your build process to enhance the classes. If using maven and hibernate >=4.2.8 then you should just be able to the relevant plugin to you pom.xml. See the section 'hibernate-enhance-maven-plugin' here https://dzone.com/articles/hibernate-bytecode-enhancement – Alan Hay Oct 06 '15 at 16:40
0

What does lazy mean? It means things are loaded on demand. There are two ways to make it happen: by using proxies (intercept the call in the proxy and load the thing) or by bytecode enhancement (modify the bytecode of the entity class so that lazy access is intercepted).

Since you cannot make a proxy for byte[], the second approach is the only eligible one.

However, you could extract the lob to a separate lazily-loaded entity, as described here.

Community
  • 1
  • 1
Dragan Bozanovic
  • 21,631
  • 4
  • 36
  • 100