lunedì 23 aprile 2012

JPA Bulk Update e optimistic locking

In JPQL per Bulk Updates si intendono aggiornamenti massivi degli archivi.
Nel seguente esempio (tratto dal libro  EJB In Action) è proposto prima il metodo tradizionale di update singoli , ossia questo:

Query query = em.createQuery(
"SELECT s FROM Seller s WHERE s.createDate <= ?1");
...
List sellers = query.getResultList();
Iterator i = seller.iterator();
while (i.hasNext()) {
Seller seller = (seller) i.next();
Seller.setStatus("Gold");
}


Con il meccanismo del bulk update in sostanza si scrive un unico update con una data di filtro e quindi lo si esegue, l’update dato alla query sarà il seguente:

Update Seller s
SET s.status = 'Gold' WHERE s.createDate <= ?1

Bisogna però ricordarsi che nel caso dei bulk update non funziona l’ optimistic locking !

Quindi i campi version, anche se correttamente presenti e definiti con l’annotation @Version ,non vengono aggiornati ed è possibile incappare nel problema degli stale objects.

giovedì 19 aprile 2012

Java Web Gestione Versioning

 
Lo scopo di questo post è mostrare una soluzione di aggiornamento versione sw Web, automatizzando la creazione della versione con uno script di ant e quindi mostrando sulle pagine della Web App la versione a cui si riferiscono.

L’effetto finale sarà di questo tipo:




I valori della versione sono presi dal file MANIFEST.MF presente dentro la directory WebContent/META-INF del progetto.  Il MANIFEST  è così definito:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.6.0_29-b11 (Sun Microsystems Inc.)
Company: NOME AZIENDA
Author: Mario Rossi
Implementation-Title: PROGETTO TEST
Implementation-Version: 1.0.1
Implementation-Build: 1
Build-time: 19/04/2012 01:58:59


La lettura di questi valori avviene all’interno di una servlet denominata InitServlet  ( utilizzando la classe Manifest definita nel package java.util.jar ) e posta come caricamento allo start up dell’applicazione (parametro <load-on-startup>0</load-on-startup> definito sul web.xml).

Il metodo init della servlet si presenta in questo modo:

public void init(ServletConfig servletConfig) throws ServletException {
      try
      {
      ServletContext servletCtx = servletConfig.getServletContext();
      String contextRoot = servletCtx.getRealPath("");
      String fManifest = contextRoot+File.separator+"META-INF"+File.separator+"MANIFEST.MF";
      InputStream stream =new FileInputStream(fManifest);
      Manifest manifest = new Manifest( stream);
      Attributes attr = manifest.getMainAttributes();
      String SOFTWARE_VERSION = attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
      servletCtx.setAttribute( "IMPLEMENTATION_VERSION", SOFTWARE_VERSION);
      String BUIL_TIME = attr.getValue("Build-time");
      servletCtx.setAttribute( "BUILT_TIME", BUIL_TIME);
      }
      catch(Exception ex){
            ex.printStackTrace();
      }
    }

A questo punto definiamo una jsp che si occupi di recuperare i valori salvati nel contesto dell’applicazione e di mostrarli a video.

Di seguito il codice:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
      String webVersion = (String)getServletConfig().getServletContext().getAttribute("IMPLEMENTATION_VERSION");

      if(webVersion == null){
            webVersion = "undefined";
      }
      if (webVersion.equals("${build.version}")){
            webVersion = "sviluppo";
      }

      String buildTime = (String)getServletConfig().getServletContext().getAttribute("BUILT_TIME");
      if(buildTime == null){
            buildTime = "undefined";
      }
      String versione = "Versione "+webVersion +" del "+buildTime;
      request.setAttribute("versione", versione);
%>


<table width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr>
            <td>
                  ${versione}<br/><br/><br/>
            </td>
           
      </tr>
</table>


Tale jsp sarà inclusa nelle nostre pagine Web tramite il classico <jsp:include page=”version.jsp”></jsp:include>

Si può automatizzare il processo di creazione versione ricorrendo ad un semplice script di Ant, che chiede all’utente di impostare la versione e quindi aggiorna il manifest. Ho definito quindi allo stesso livello della directory src una directory ant con la seguente struttura:




versionCreator.xml è così definito:

<?xml version="1.0" encoding="UTF-8"?>
<project name="PROGETTO_AGGIORNAMENTO_VERSIONE" basedir="../" >
<property name="myManifest" value="${basedir}/WebContent" />
<tstamp>
                  <format property="date" pattern="ddMMyyyy" locale="it"/>
                  <format property="dateManifest" pattern="dd/MM/yyyy" locale="it"/>
                  <format property="timeManifest" pattern="hh:mm:ss"   locale="it"/>
      </tstamp>
      <target name="init" >
                  <description>Prepare for a build tasks</description>
                  <property file="ant/versioning/build.version"/>
                  <property name="current.build.version" value="${current.build.version}"/>
                  <buildnumber file="ant/versioning/build.number"/>
                  <echo message="${line.separator}x.x.0 - Bug-Fix${line.separator}x.0.x - Nuova funzionalità${line.separator}0.x.x - Nuova Versione"/>
                  <input message="Versione attuale: ${current.build.version}${line.separator}Inserire una nuova versione (di default è quella attuale):"
                           addproperty="build.version"
                           defaultvalue="${current.build.version}"
                  />
<echo file="ant/versioning/build.version">current.build.version=${build.version}</echo>
            </target>
<target name="manifest" depends="init" description="Prepare manifest file" >
                  <mkdir dir="${myMainifest}/META-INF" />
                  <manifest file="${myManifest}/META-INF/MANIFEST.MF">
                        <attribute name="Company" value="NOME AZIENDA"/>
                        <attribute name="Author" value="Mario Rossi"/>
                        <attribute name="Implementation-Title" value="PROGETTO TEST"/>
                        <attribute name="Implementation-Version" value="${build.version}"/>
                        <attribute name="Implementation-Build"   value="${build.number}"/>
                        <attribute name="Build-time"   value="${dateManifest} ${timeManifest}"/>
                  </manifest>
                  <echo message="Created directory ${myManifest}/META-INF" />
            </target>
</project>




Lanciando da Eclipse il target manifest verrà chiesto di impostare la versione, riportando la versione attualmente presente come valore di default  nella casella di testo.
In questo modo:







mercoledì 18 aprile 2012

Ruoli nell'architettura degli EJB

Questo è quanto ho capito riguardo la suddivisione dei ruoli nell'ambito dell'architettura degli EJB.
La specifica definisce i 7 ruoli diversi che ci dovrebbero essere in un mondo "ideale",  motivando così le peculiarità di ogni ruolo.



System Administrator

L’amministratore di sistema è responsabile della configurazione e amministrazione della infrastruttura di rete che include l’EJB Server ed il Container. E’ inoltre responsabile del controllo e monitoraggio degli EJB deployati.

Bean Provider

Il bean provider è tipicamente un esperto del dominio applicativo .
Realizza EJB riutilizzabili che implementano logiche di business oppure business entities. Non è richiesto che sia un esperto di tematiche come la transazionalità, la concorrenza la security ecc.
Tutte queste tematiche sono demandate all’EJB Container.

Application Assembler

E’ un esperto anche lui del dominio applicativo che si occupa di comporre applicazioni (tipicamente Web application) integrandole con gli EJB forniti dal bean provider.
Lavora quindi con il deployment descriptor dell’EJB e con le interfacce fornite, senza avere conoscenza dei dettagli implementativi degli stessi EJB, che sono a  carico del bean provider.
 
Deployer

Il deployer si occupa dell’installazione sull’AS degli EJB ricevuti dal Bean Provider o dall’Application Assembler.

EJB Server Provider

E’ uno specialista e conoscitore dell’application server su cui gira l’applicazione che utilizza gli EJB.

EJB Container Provider

E’ una sorta di incrocio tra l’application assembler e l’EJB Service Provider, fornisce principalmente:
  • Tool a supporto del deploy degli EJB;
  • Supporto e assistenza a runtime per gli EJB deplorati.


Persistence Provider

E’ l’esperto del mondo ORM, possiamo rozzamente definirlo il persistence DBA, conosce bene il motore di persistenza utilizzato (Hibernate, IBATIS, etc.) e come ottimizzarlo conoscendo  anche il DB sottostante             



martedì 10 aprile 2012

Eliminare un account da Ubuntu

Per eliminare definitivamente un account su Ubuntu:

  1. Accedere al terminale (CTR+ALT+T);
  2. Digitare sudo userdel -r nomeUtente (verrà chiesta la password di amministratore).

Display Table tornare indietro su lista dati paginata

Utilizzando display tag spesso ci si imbatte in questo scenario.
Abbiamo una lista di dati paginata e linkata, quindi cliccando su un elemento si accede ad un dettaglio su un’altra pagina e da questa pagina si vuole tornare indietro esattamente nella lista paginata di partenza (es si era a pagina 3 di 4 e si vuole tornare esattamente lì e non alla pagina iniziale).
La display table di dispay tag utilizza un identificatore univoco per tabella sia per la paginazione che per l’ordinamento.
Tale identificatore è visibile in querystring quando si naviga da una pagina all’altra.
Sono possibili quindi 2 approcci.

Soluzione 1

Si prende nota dell’identificatore generato dalla display-table.
Quindi nella jsp di partenza (nella griglia di dati), si inserisce un codice di questo tipo:

<% String numPag=request.getParameter("d-49653-p")==null?"1":request.getParameter("d-49653-p");
   session.setAttribute("numPag", numPag);
%>


In modo che ad ogni paginazione il valore del numero di pagina sia salvato in sessione prendendolo dalla request.

Sulla jsp di destinazione avremo invece:

<a href="index.jsp?d-49653-p=${numPag}">Indietro</a>

Soluzione 2

In questo caso si realizza un filtro http che provvede ad analizzare la queryString e quando trova una espressione che identifica l’indicatore di pagina della display table mette in sessione il valore.
Quindi la jsp di partenza non avrà nessun codice particolare, la jsp di destinazione invece sarà uguale a quella vista nella soluzione 1.
Il filtro http invece avrà il seguente codice nel metodo doFilter.


public void doFilter(ServletRequest request, ServletResponse response,
                                   FilterChain chain) throws IOException, ServletException {
                        HttpServletRequest req = (HttpServletRequest) request;

                        String query_string = req.getQueryString();
                        if (null != query_string && query_string.length() > 0) {
                                   Pattern p = Pattern.compile("d-\\d*-p=(\\d*)");
                                   Matcher m = p.matcher(query_string);
                                   if (m.find()) {
                                               String val = m.group(1);

                                               req.getSession().setAttribute("numPag", val);

                                   }

                        }

                        chain.doFilter(request, response);
            }

La regular expression indicata in grassetto intercetta tutti i paramentri costituiti da una struttura del tipo d-[numeri]-p=[numeroPagina] e consentirà di intercettare quindi tutti i flag di paginazione di qualunque display table.
In questo modo quindi si evita di toccare ogni jsp annotando mettendo esplicitamente in sessione il valore della paginazione (anche se di tale valore bisogna comunque prendere nota per mostrarlo sulla jsp di arrivo alla pressione del tasto indietro).

lunedì 9 aprile 2012

JPA Query con clausola ORDER BY

C'è una differenza fondamentale nell'eseguire una query sql con clausola order by rispetto ad una query JPA.
Data la seguente tabella SQL:

CREATE TABLE `BIDS` (
  `bid_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `bidder_id` varchar(45) DEFAULT NULL,
  `item_id` int(10) unsigned DEFAULT NULL,
  `bid_price` double DEFAULT NULL,
  `bid_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`bid_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1


E' perfettamente lecito in sql scrivere la seguente query:


select b.bid_id from BIDS b  order by b.bid_price desc;

Quindi avere nell'order  by un campo non incluso nella clausola select.

In una query JPA ciò NON E' POSSIBILE in quanto i campi presenti nell'order by devono essere parte della proiezione in select.
Quindi, ipotizzando che la tabella sia mappata come oggetto con gli stessi nomi in sql
scrivere la stessa query precedentemente riportata genererà un errore.

Verificare se il sistema operativo è a 32 o 64 bit su UBUNTU

Per vedere se il kernel linux installato è a 32 bit o a 34 bit digitare:

uname -m

I risultati possono essere:

  • x86_64 se è a 64 bit;
  • i686 se è a  32 bit.
Invece per vedere se la cpu del computer è a 32 bit o a 64 bit digitare:

cat /proc/cpuinfo | grep flags

 Con questo comando ricerchiamo nel testo il punto dove è presente la property flags nel file cpuinfo.

Quindi:
  • Se è presente la dicitura tm (transparent mode) allora è a 32 bit;
  • Se è presente la dicitura rm (real mode) è a 16 bit;
  • Se è presente la dicitura lm (long mode) è a 64 bit.

 
 

sabato 7 aprile 2012

@MappedSuperClass

Usando questa annotation è possibile definire una classe senza associarla direttamente ad una tabella.
Quindi le entità JPA potranno poi estendere tale classe e in questo caso si effettueranno le mappature dei campi della classe annotata con @MappedSuperClass.
Un esempio chiaro di utilizzo si trova sul javadoc della JEE 5 (http://docs.oracle.com/javaee/5/api/javax/persistence/MappedSuperclass.html)