Visualizzazione post con etichetta hibernate. Mostra tutti i post
Visualizzazione post con etichetta hibernate. Mostra tutti i post

mercoledì 20 maggio 2009

Hibernate: generate toString() and equals() [ENG]

If you want Hibernate Tools to generate toString() and equals() methods picking some fields from .hbm.xml mapping files you may use these meta-tags:

<id name="id" type="long">
        <meta attribute="use-in-tostring">true</meta>
        <meta attribute="use-in-equals">true</meta>
        <column name="id" />
</id>
<property name="number" type="string" unique-key="UK_t_table1">
        <meta attribute="use-in-tostring">true</meta>
        <column name="number" length="5" />
</property>

martedì 9 settembre 2008

Hibernate Tools: Custom Reverse Engineering/2

Gli Hibernate Tools fanno un discreto lavoro per il reverse Engineering del database, e già personalizzare i modelli usati per la generazione automatica del codice permette di incrementare la produttività.

Si può anche personalizzare la naming convention. Di default infatti una tabella t_utenti verrebbe mappata come TUtenti; se volessimo modificare questo comportamento (magari per togliere il prefisso "T" convenzionale nel database ma abbastanza inutile nel contesto OOP) dovremmo creare una nostra classe che faccia l'override del metodo tableToClassName:

package reveng;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.TableIdentifier;

public class CustomReverseEngineeringStrategy extends DelegatingReverseEngineeringStrategy
{

  private static final String TABLE_PREFIX = "t_";

  private Properties properties = null;
  
  public CustomReverseEngineeringStrategy(ReverseEngineeringStrategy delegate)
  {
    super(delegate);
    try
    {
      properties = getPropertiesFromClasspath("reveng.properties");
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  public static Properties getPropertiesFromClasspath(String propFileName) throws IOException
  {
    
    if (propFileName==null || "".equals(propFileName)) return null;
    
    Properties props = new Properties();
    InputStream inputStream = getInputStreamFromClasspath(propFileName);

    if (inputStream != null)
    {
      props.load(inputStream);
      return props;     
    }

    else
    {
      return null;
    }
  }

  public static InputStream getInputStreamFromClasspath(String resourceFileName)
  {
    return CustomReverseEngineeringStrategy.class.getResourceAsStream(resourceFileName);
  }
  
  @Override
  /**
   * Genera il nome della classe a partire dal nome della tabella, ignorando il prefisso "t_"
   */
  public String tableToClassName(TableIdentifier tableIdentifier)
  {
    String tableName = tableIdentifier.getName();
    
    String className = super.tableToClassName(tableIdentifier);
    String qualifiedName = getPackageName(className);
    
    // default
    String result = className;
    
    // proprietà mappata
    String mappedProperty = (String) properties.get("table."+tableName);
    if (mappedProperty != null && mappedProperty.length()>0)
    {
      result = qualifiedName + "." + mappedProperty;
    }
    // proprietà non mappata, rimuovo il prefisso delle tabelle - se presente
    else if (tableName.startsWith(TABLE_PREFIX))
    {
      String cleanClassName = getClassName(className).substring(1);
      result = qualifiedName + "." + cleanClassName;  
    }
    
    return result;
  }
  
  public String getPackageName(String fullyQualifiedName)
  {
    int dotIndex = fullyQualifiedName.lastIndexOf('.');
    return fullyQualifiedName.substring(0, dotIndex);
  }

  public String getClassName(String fullyQualifiedName)
  {
    int dotIndex = fullyQualifiedName.lastIndexOf('.');
    return fullyQualifiedName.substring(dotIndex+1);
  }
  
  public static void main(String[] args)
  {
    CustomReverseEngineeringStrategy cres = new   CustomReverseEngineeringStrategy(null);
    System.out.println(cres.getPackageName("it.package.test.Class1"));
    System.out.println(cres.getClassName("it.package.test.Class1"));
  }
  
}
NOTA: questa classe tra l'altro cerca un file .properties nel quale siano definite le chiavi table.t_nome_tabella=NomeClasse per un ulteriore livello di personalizzazione.
NOTA2: il metodo main serve solo per effettuare un test

Hibernate Tools: Custom Reverse Engineering/1

Hibernate non sarebbe granché utile se non fosse accompagnato da strumenti che permettono di creare automaticamente le classi POJO, i DAO e i mapping. Cionondimeno il comportamento standard dei tool (v. JBoss Tools) potrebbe non essere quello desiderato.
La configurazione di base si può cambiare aggiustando il file reveng.xml, ma si può andare ben oltre. Ad esempio si potrebbe volere un codice diverso per i DAO (che JBoss Tools chiama "Home") che forniscono - tabella per tabella - gli strumenti di base per cercare, inserire, modificare e cancellare record.
A tal fine è necessario recuperare il template del file in questione dal JAR hibernate-tools che in genere si trova nella cartella del plugin di Eclipse. Una volta scompattata la cartella (conservando la struttura dei package) si possono modificare i file *.ftl desiderati e cancellare quelli non intessanti (il tool prenderà quelli standard dal jar). Bisogna anche far puntare il tool alla cartella dei nuovi template, nella configurazione di lancio.