HQL – Like parameter

Hql con un parametro in input da mettere nella like con le percentuali:

String querySql = "select u from Users u  ";
String whereSql = whereSql + " u.currentLocation like :currentLocation";
querySql = querySql + whereSql;

Query q = this.getEntityManager().createQuery(querySql);
q.setParameter("currentLocation", '%'+user.getCurrentLocation()+'%');

Hibernate: Mappatura many to many (xml)

Many-to-many  si ha quando un record di una tabella può essere collegato con tanti record su un altra tabella,e viceversa. 

ogni PERSONA può avere più CONTICORRENTI  e ogni CONTOCORRENTE può appartanere a più PERSONE.


File : Persona.java
package com.prova;
 import java.util.HashSet;
import java.util.Set;
 public class Persona implements java.io.Serializable {
  private Integer personaId;
private Set<ContoCorrente> contiCorrenti= new HashSet<ContoCorrente>(0);
  //getter, setter and constructor
}

File : ContoCorrente.java
package com.prova; 
import java.util.HashSet;
import java.util.Set;
 public class ContoCorrente implements java.io.Serializable {
  private Integer contoCorrenteId;
private Set<Persona> persone= new HashSet<Persone>(0);
  //getter, setter and constructor
}


File : Persona.hbm.xml
    <class name=”com.prova.Persona” table=”persona” catalog=”provadb”>
        <id name=”personaId” type=”java.lang.Integer”>
            <column name=”PERSONA_ID” />
            <generator class=”identity” />
        </id>
        <set name=”conticorrenti” table=”unione” 
         inverse=”false” lazy=”true” fetch=”select” cascade=”all” >
            <key>
                <column name=”PERSONA_ID” not-null=”true” />
            </key>
            <many-to-many entity-name=”com.prova.ContoCorrente”>
                <column name=”CONTO_CORRENTE_ID” not-null=”true” />
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>




File : ContoCorrente.hbm.xml
<hibernate-mapping>
    <class name=”com.prova.ContoCorrente” table=”contocorrente” catalog=”mkyongdb”>
        <id name=”contoCorrenteId” type=”java.lang.Integer”>
            <column name=”CONTO_CORRENTE_ID” />
            <generator class=”identity” />
        </id>
       <set name=”persone” table=”unione” inverse=”true” lazy=”true” fetch=”select”>
            <key>
                <column name=”CONTO_CORRENTE_ID” not-null=”true” />
            </key>
            <many-to-many entity-name=”com.prova.Persona”>
                <column name=”PERSONA_ID” not-null=”true” />
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>


Testiamo il tutto

File : App.java
public class App {
public static void main(String[] args) {
        System.out.println(“Hibernate many to many (XML Mapping)”);
Session session = HibernateUtil.getSessionFactory().openSession();
  session.beginTransaction();
  Persona persona = new Persona();
        ContoCorrente contoCorrente1 = new ContoCorrente ();
        ContoCorrente  contoCorrente2= new ContoCorrente ();
        Set<ContoCorrente > contoCorrenti= new HashSet<ContoCorrente >();
        contoCorrenti.add(contoCorrente1 );
        contoCorrenti.add(contoCorrente1 );
        persona.setContiCorrenti(contoCorrenti);
        session.save(persona);
  session.getTransaction().commit();
System.out.println(“Done”);
}
}

Hibernate: Strategie di Fetch

Quando si a che fare con delle entity (padre) che hanno delle collection di altre entity (figli),  Hibernate offre la possibilità di “tirare su” dal db la collection dei figli subito, nel momento in cui si accede al padre, o in un secondo momento, quando si cerca di accedere direttamente ai figli.
L’attributo che indica QUANDO prendere la collection dal db è  lazy=”true|false”. Con true,detto anche comportamento lazy, l’oggetto figlio sarà preso dal db solo nel momento in cui viene invocato. Questo fa si che le query siano molto veloci, si prendono dal db solo i padri, però, se la lettura dei figli avviene fuori dal contesto di hibernate (come ad esempio un EJB),  potremmo avere che la sessione è chiusa e quindi verrà sollevata una exception. 
Con  lazy = “false”, detto anche comportamento eager, non avremo problemi di sessione chiusa  ma le prestazioni potrebbero decadere in quanto con una singola query si potrebbe tirare su  tutto il DB.
Per indicare COME i figli devono essere letti dal db si l’attributo fetch = “select|subselect|join|batch”.
select: una seconda select è usata per leggere la collection,  quindi Hibernate eseguirà  una select per il padre e una select per i  figli. 
Se, per esempio, abbiamo 10 entity padre (A) e ciascuna padre ha al suo interno una collection  di figli (B) di grandezza qualsiasi, verranno eseguite le seguenti select:
select  A –> eseguita  1 volta, ci darà tutti i padri che ci interessano
select B where A.Id = ? —-> eseguita altre 10 volte
avremo quindi in totale 11 select eseguite.  Questa opzione è quella di default. 
join:  verrà eseguita un’unica select, mettendo in JOIN il padre con  tutti i suoi figli. 
batch-size=N: questo è un  po contorto, esso indica non quanti elementi della collection devono essere letti ma indica quante collection devono essere lette. Riconsiderando l’esempio precendente, se  batch-size = 5 leggeremo al  massimo 5 collection di figli per volta
select A —> 1 volta
select B where A.id in ( ?, ?, ?, ?, ? )  –> eseguito 10/5= 2 volte
le select totali questa volta sono 3,  al posto delle 11 select richieste normalmente, un bel risparmio di tempo.
subselect: hibernate utilizzerà le subquery. In questo caso le select generate sono
select A—> 1 volta
select B where A.id  in ( select A  )     –>   1 volta
quindi in questo caso avremo 2 select in tutto. 
Ogni opzione ha i suoi pro e i suoi contro, molto dipende dal tipo di DB usato e dalla complessità dello schema.