[Spring] Spring3: dai Controller ai Repository [Parte2]

In questa Parte 2 del tutorial di Spring3, vengono mostrate alcune classi di esempio con relative annotazioni per ciascuno strato della nostra web application:

  • strato controller (Spring MVC): annotazione @Controller
  • strato di business logic: annotazione @Service
  • strato di persistenza e modellazione dei dati (Spring ORM): annotazioni @Entity e @Repository

Model @Entity

Riporto qui di seguito un esempio di model o entity, che mappa una tabella sul database con relative associazioni ad altre entità. Il model viene annotato con @Entity e deve essere enumerato nelle annotatedClass del file spring-orm.xml, visto nella Parte1 di questo tutorial. Per maggiori informazioni, leggere anche Hibernate Annotations.

Nell’esempio sono riportate anche delle annotazioni per la validazione dei campi del model (javax.validation e org.hibernate.validator.constraints), che spostano la validazione lato server verso il lato persistenza e che Spring intercetta e gestisce con opportuni messaggi di stato.

package com.yourDomain.model;

import com.yourDomain.interceptors.IAuditLog;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;

@Entity
@Table(name="utenti")
@NamedQueries({
	@NamedQuery(name = "Utente.findAll", query = "from Utente where id!=-1 order by cognome"),
	@NamedQuery(name = "Utente.findById", query = "from Utente r where r.id = :idUtente"),
	@NamedQuery(name = "Utente.findByCodiceFiscaleAndEmail", query = "from Utente r where lower(r.codiceFiscale) = lower(:codiceFiscale) and lower(r.email) = lower(:email) and dataCancellazione is null and abilitato = true"),
	@NamedQuery(name = "Utente.findByCodiceFiscaleOrEmail", query = "from Utente r where (lower(r.codiceFiscale) = lower(:codiceFiscale) or lower(r.email) = lower(:email) ) and dataCancellazione is null")
})
public class Utente implements Serializable,IAuditLog {

	private static final long serialVersionUID = 8797826874630455491L;

	public static final Integer ID_ADMINISTRATOR = -1;

	@Id
	@GeneratedValue
	@Column(name="id")
	private Integer id;

	@Column(name="matricola",nullable=true,length=50)
	private String matricola;

	@Column(name="cognome",nullable=false,length=255)
	@NotEmpty
	@NotNull
	private String cognome;

	@Column(name="nome",nullable=false,length=255)
	@NotEmpty
	@NotNull
	private String nome;

	@ManyToOne(fetch=FetchType.EAGER, targetEntity=StatoCivile.class)
	@JoinColumn(name = "fk_stato_civile", nullable = true, referencedColumnName = "id")
	private StatoCivile statoCivile;

	@Column(name="codice_fiscale",nullable=true,length=16)
	@NotEmpty
	@NotNull
	@Pattern(regexp="^[a-zA-Z]{6}[0-9]{2}[abcdehlmprstABCDEHLMPRST]{1}[0-9]{2}([a-zA-Z]{1}[0-9]{3})[a-zA-Z]{1}$")
	private String codiceFiscale;

	@Column(name="data_nascita",nullable=true)
	@Temporal(TemporalType.DATE)
	@DateTimeFormat(pattern="dd/MM/yyyy")
	private Date dataNascita;

	@ManyToOne(fetch=FetchType.EAGER, targetEntity=Comune.class)
	@JoinColumn(name = "fk_comune_nascita", nullable = true, referencedColumnName = "id")
	private Comune comuneNascita;

	@ManyToOne(fetch=FetchType.EAGER, targetEntity=Stato.class)
	@JoinColumn(name = "fk_stato_nascita", nullable = true, referencedColumnName = "id")
	private Stato statoNascita;

	@Column(name="indirizzo_residenza",length=255,nullable=true)
	private String indirizzoResidenza;

	@Column(name="cap_residenza",length=5,nullable=true)
	@Length(min=0,max=5)
	@Pattern(regexp="^[0-9]{0,5}")
	private String capResidenza;

	@ManyToOne(fetch=FetchType.EAGER, targetEntity=Comune.class)
	@JoinColumn(name = "fk_comune_residenza", nullable = true, referencedColumnName = "id")
	private Comune comuneResidenza;

	@Column(name="email",length=255,nullable=false)
	@NotEmpty
	@NotNull
	@Email
	private String email;

	@Column(name="partita_stipendio",length=50,nullable=true)
	private String partitaStipendio;

	@Column(name="sesso",length=1,nullable=true)
	@NotEmpty
	@NotNull
	private String sesso;

	@Column(name="telefono",length=100,nullable=true)
	//@Pattern(regexp="^(1\\s*[-\\/\\.]?)?(\\((\\d{3})\\)|(\\d{3}))\\s*[-\\/\\.]?\\s*(\\d{3})\\s*[-\\/\\.]?\\s*(\\\\d{4})\\s*(([xX]|[eE][xX][tT])\\.?\\s*(\\d+))*$")
	private String telefono;

	@Column(name="fax",length=100,nullable=true)
	//@Pattern(regexp="^(1\\s*[-\\/\\.]?)?(\\((\\d{3})\\)|(\\d{3}))\\s*[-\\/\\.]?\\s*(\\d{3})\\s*[-\\/\\.]?\\s*(\\\\d{4})\\s*(([xX]|[eE][xX][tT])\\.?\\s*(\\d+))*$")
	private String fax;

	@Column(name="cellulare",length=100,nullable=true)
	//@Pattern(regexp="^(1\\s*[-\\/\\.]?)?(\\((\\d{3})\\)|(\\d{3}))\\s*[-\\/\\.]?\\s*(\\d{3})\\s*[-\\/\\.]?\\s*(\\\\d{4})\\s*(([xX]|[eE][xX][tT])\\.?\\s*(\\d+))*$")
	private String cellulare;

	@Column(name="codice_abi",length=100,nullable=true)
	private String codiceABI;

	@Column(name="codice_cab",length=100,nullable=true)
	private String codiceCAB;

	@Column(name="numero_figli",nullable=true)
	private Integer numeroFigli;

	@Column(name="perc_invalidita",length=100,nullable=true)
	//@Pattern(regexp="^\\d+((\\.|,)\\d+)?$")
	private String percentualeInvalidita;

	@ManyToOne(fetch=FetchType.EAGER, targetEntity=AlboProfessionale.class)
	@JoinColumn(name = "fk_albo_professionale", nullable = true, referencedColumnName = "id")
	private AlboProfessionale alboProfessionale;

	@ManyToOne(fetch=FetchType.EAGER, targetEntity=SpecializzazioneProfessionale.class)
	@JoinColumn(name = "fk_spec_professionale", nullable = true, referencedColumnName = "id")
	private SpecializzazioneProfessionale specializzazioneProfessionale;

	@Column(name="data_modifica",nullable=true)
	@Temporal(TemporalType.DATE)
	@DateTimeFormat(pattern="dd/MM/yyyy")
	private Date dataModifica;

	@Column(name="data_creazione",nullable=true)
	@Temporal(TemporalType.DATE)
	@DateTimeFormat(pattern="dd/MM/yyyy")
	private Date dataCreazione;

	@Column(name="data_cancellazione",nullable=true)
	@Temporal(TemporalType.DATE)
	@DateTimeFormat(pattern="dd/MM/yyyy")
	private Date dataCancellazione;

	@Column(name="data_ultimo_accesso",nullable=true)
	@Temporal(TemporalType.DATE)
	@DateTimeFormat(pattern="dd/MM/yyyy")
	private Date dataUltimoAccesso;

	@ManyToOne(fetch=FetchType.LAZY, targetEntity=Utente.class)
	@JoinColumn(name = "fk_utente_modifica", nullable = true, referencedColumnName = "id")
	private Utente utenteModifica;

	@Column(name="abilitato",nullable=false)
	private boolean abilitato = true;

	@ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL,targetEntity=GruppoOperativo.class)
	@JoinTable(name = "associativa_utenti_gruppi",
			joinColumns = @JoinColumn(name = "fk_Utente", referencedColumnName = "id"),
			inverseJoinColumns = @JoinColumn(name = "fk_gruppo", referencedColumnName = "id")
	)
	private List<GruppoOperativo> gruppiOperativi;

	@ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL,targetEntity=TitoloStudio.class)
	@JoinTable(name = "associativa_utenti_titolistudio",
			joinColumns = @JoinColumn(name = "fk_Utente", referencedColumnName = "id"),
			inverseJoinColumns = @JoinColumn(name = "fk_titolo_studio", referencedColumnName = "id")
	)
	private Set<TitoloStudio> titoliStudio;

	@OneToMany(mappedBy = "Utente", cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity=Rapporto.class)
	private List<Rapporto> rapporti;

	//@Column(name="nato_estero",nullable=true)
	@Transient
	private boolean natoInStatoEstero;

	@Transient
	private boolean isLogged;

	@Transient
	private String maxVisibility;

	public Utente(){

	}

/**
    QUI TUTTI I METODI DI GET E SET
**/

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Utente other = (Utente) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

}

 

@Controller

Il controller è una interfaccia che riceve una richiesta HTTP – HttpServletRequest e HttpServletResponse – simile alla Action di Struts. Dunque, definisce lo strato di interfaccia tra presentation e business layer. L’annotazione da utilizzare è @Controller e per permettere a Spring MVC di effettuare l’autowiring in fase di startup della web app occorre inserire nel file di configurazione (spring-application.xml) il tag mvc:annotation-driven (come visto nella Parte1). Nel seguente esempio, vengono annotati anche gli editors, che sono utili per popolare dinamicamente select o checkbox lato template. L’annotazione @InitBinder serve per configurare il controller allo startup della web application (in questo caso, a registrare la lista degli Editors). Con @Autowired viene iniettato il servizio che verrà utilizzato dal controller.

Non è necessaria una interfaccia da implementare, ma occorre solo annotare la classe con @Controller, in quanto il controller stesso non viene “iniettato”.

Per maggiori dettagli sui controller e su Spring MVC, leggere questo link: Web MVC Framework.

package com.yourDomain.controller;

import com.yourDomain.model.Profilo;
import com.yourDomain.model.Rapporto;
import com.yourDomain.model.Utente;

import java.beans.PropertyEditorSupport;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/anagraficautente")
@SessionAttributes({"utenteLoggato","utenteSelezionato"})
public class UtenteController {

	protected static Logger log = Logger.getLogger(UtenteController.class);

	@Autowired
	UtenteService UtenteService;

	@InitBinder
	public void initBinder(WebDataBinder b) {
		DateFormat dateFormat = new SimpleDateFormat(SiapConfigProperties.getValue("dateFormat.small"));
		b.registerCustomEditor(Profilo.class, new ProfiloEditor());
	}

	//EDITOR
	private class DateEditor extends CustomDateEditor {

		public DateEditor(DateFormat dateFormat, boolean allowEmpty) {

			super(dateFormat, allowEmpty);
			// TODO Auto-generated constructor stub
			}
			@Override
			public void setAsText(String text) throws IllegalArgumentException {
				try {
					if(!Utils.isEmpty(text)){
						DateFormat df = new SimpleDateFormat(SiapConfigProperties.getValue("dateFormat.small"));
						setValue(df.parse(text));
					}
				} catch (Exception e) {
					setValue(null);
				}
		    }
		    @Override
		    public String getAsText() {
		    	if(((Date) getValue()) == null)
		    		return "";

		    	DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
		        return ((String) formatter.format(getValue()));
		    }
	}

	//EDITOR
	private class ProfiloEditor extends PropertyEditorSupport {
			@Override
			public void setAsText(String text) throws IllegalArgumentException {
				try {
					if(!Utils.isEmpty(text)){
						Profilo profilo = profiloService.getProfilo(Integer.valueOf(text));
						if(profilo.getId()==null)setValue(null);
						else setValue(profilo);
					}
				} catch (Exception e) {
					setValue(null);
				}
		    }
		    @Override
		    public String getAsText() {
		    	if((Profilo) getValue() == null ||((Profilo) getValue()).getId()==null)
		    		return "";
		    	String id = ((Profilo) getValue()).getId().toString();
		        return id;
		    }
	}

	@RequestMapping(value = "/utente", method = {RequestMethod.GET,RequestMethod.POST})
	public ModelAndView redirectToAnagraficaUtente(@RequestParam(value = "id", required = false) String id,
			HttpSession session,
			ModelAndView mav) {

		try{
			Utente Utente = null;

			if(id == null && session.getAttribute("UtenteSelezionata") != null){
				Utente = (Utente)session.getAttribute("UtenteSelezionata");
			}else if(id != null){
				if(id != ""){
					Utente = UtenteService.getUtente(Integer.parseInt(id));
				}else if(id == ""){
					Utente = (Utente) session.getAttribute("utenteLoggato");
				}
				mav.addObject("UtenteSelezionata", Utente);
			}

			if(Utente == null){
				mav.addObject("result", ResultBean.writeMessageByKey(ResultBean.ERROR, "Utente.storico.error"));
				mav.setViewName(MappingMavController.STORICO_CARRIERA_JSP);

			}

			mav.setViewName("/anagraficaUtente");

		} catch (Exception e) {
			mav.addObject("result", ResultBean.writeMessageByKey(ResultBean.ERROR, "error.generic"));
			log.error("UtenteController - metodo redirectToAnagraficaUtente: ",e);
		}	

		return mav;
	}

}

 

@Service

Con l’annotazione @Service viene definita la classe di servizio con la logica di business, iniettata nel controller o in altri strati della nostra web application. Tale classe implementa una interfaccia. In tale strato è possibile definire la gestione delle transazioni, sia mappando le regole sul file spring-orm.xml, come visto nella Parte1, che inserendo sulla classe di servizio (gestione globale della transazione) e sui singoli metodi (gestione locale della transazione) l’annotazione @Transactional (definendo il tipo di propagazione, come avviene negli EJB). In tale classe vengono “iniettati” anche i DAO per la comunicazione con il database o altre classi di servizio (annotazione @Autowired).

package com.yourDomain.service;

import com.yourDomain.model.Utente;
import java.util.Map;

public interface UtenteService {
	Utente getUtenteByCodiceFiscaleAndEmail (String codiceFiscale, String email) throws Exception;
	boolean updateUtente (Utente Utente) throws Exception;
	public Map<String,String> getContestiAndOperazioniUtente (Utente Utente) throws Exception;
}


package it.beniculturali.siapweb.service.impl;

import it.beniculturali.siapweb.dao.ContestoDao;
import it.beniculturali.siapweb.dao.UtenteDao;
import it.beniculturali.siapweb.model.Contesto;
import it.beniculturali.siapweb.model.Utente;
import it.beniculturali.siapweb.service.UtenteService;
import it.beniculturali.siapweb.utilities.Utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service("utenteService")
@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
public class UtenteServiceImpl implements UtenteService {

	protected static Logger log = Logger.getLogger(UtenteServiceImpl.class);

	public UtenteServiceImpl(){

	}

	@Autowired
	private ContestoDao contestoDao;

	@Autowired
	private UtenteDao utenteDao;

	@Override
	/**
	 * metodo che ritorna la utente con un dato codice fiscale e una email
	 *
	 * @param codiceFiscale, email
	 * @return Utente
	 *
	 */
	public Utente getUtenteByCodiceFiscaleAndEmail (String codiceFiscale, String email) throws Exception{
		log.debug("UtenteServiceImpl - getUtenteByCodiceFiscaleAndEmail: inizio metodo");
		Utente utente = utenteDao.getUtenteByCodiceFiscaleAndEmail(codiceFiscale, email);
		log.debug("UtenteServiceImpl - getUtenteByCodiceFiscaleAndEmail: fine metodo");
		return utente;
	}

	/**
	 * metodo che aggiorna i dati di una determinata utente
	 *
	 * @param codiceFiscale, email
	 * @return Utente
	 *
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public boolean updateUtente(Utente utente) throws Exception {
		log.debug("UtenteServiceImpl - updateUtente: inizio metodo");

			boolean result = false;
			log.debug("Aggiornamento dei dati della utente con id."+utente.getId());
			result = utenteDao.updateUtente(utente);

		log.debug("UtenteServiceImpl - updateUtente: fine metodo");
		return result;
	}

	/**
	 * metodo che ritorna la mappa dei contesti di un utente con relative operazioni permesse
	 *
	 * @param utente
	 * @return
	 * @throws Exception
	 */
	@Override
	public Map<String,String> getContestiAndOperazioniUtente(Utente utente) throws Exception {
		Map<String,String> contestiUtenteMap = new HashMap<String, String>();
		log.debug("UtenteServiceImpl - getContestiAndOperazioniUtente: inizio metodo");
		try{

			List<Contesto> contestiUtente = contestoDao.getContestiAndOperazioniUtente(utente);

			//costruisco la lista delle operazioni per ogni contesto

			if(contestiUtente!=null){

				for(Contesto contestoUtente : contestiUtente){

					//costruisco la mappa con le operazioni permesse dell'utente loggato
					contestiUtenteMap.put(contestoUtente.getId().toString(), Utils.convertListStringInSingleString(contestoUtente.getTipiOperazioniUtente(),","));
				}
			}

		}
		catch(Exception e){
			log.error("ContestoDaoImpl - getContestiAndOperazioniUtente: ",e);
		}
		log.debug("UtenteServiceImpl - getContestiAndOperazioniUtente: fine metodo");
		return contestiUtenteMap;
	}

}

 

@Repository

L’annotazione @Repository definisce le classi dello strato di persistenza, ossia i cosiddetti DAO (Data Access Object). Anche qui le classi implementano una interfaccia, visto che verranno “iniettate” nello strato di servizio (con annotazione @Autowired). Qui viene iniettato anche il SessionFactory (o l’HibernateTemplate), il manager che ci permetterà di eseguire le operazioni CRUD sulla basedati definita e configurata nella Parte1 di questo tutorial.

package com.yourDomain.dao;

import com.yourDomain.model.GruppoOperativo;
import com.yourDomain.model.Utente;

import java.util.List;

public interface UtenteDao {

	List<Utente> getUtenti() throws Exception;
	Utente getUtenteByCodiceFiscaleAndEmail (String codiceFiscale, String email) throws Exception;
	boolean isUtenteRegistrato (String codiceFiscale, String email, Integer idUtente) throws Exception;
	Utente getUtente (Integer idUtente) throws Exception;
	public int countUtentiForGruppoOperativo (GruppoOperativo gruppoOperativo) throws Exception;
	boolean saveUtente(Utente nuovoUtente) throws Exception;
	boolean updateUtente(Utente risorsa) throws Exception;

}

 

package com.yourDomain.dao.impl;

import com.yourDomain.dao.UtenteDao;
import com.yourDomain.model.GruppoOperativo;
import com.yourDomain.model.Utente;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository("utenteDao")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class UtenteDaoImpl implements UtenteDao {

	@Autowired
	SessionFactory sessionFactory;

	protected static Logger log = Logger.getLogger(UtenteDaoImpl.class);

	public UtenteDaoImpl() {

	}

	/**
	 * metodo che ritorna la lista degli utenti
	 *
	 * @return List<Utente>
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Utente> getUtenti() {
		Session session = sessionFactory.getCurrentSession();
		Query query = session.getNamedQuery("Utente.findAll");
		return query.list();
	}

	/**
	 * metodo che ritorna l'utente con un dato codice fiscale e una email
	 *
	 * @param codiceFiscale
	 *            , email
	 * @return Utente
	 *
	 */
	@Override
	public Utente getUtenteByCodiceFiscaleAndEmail (String codiceFiscale, String email) throws Exception{
		Session session = sessionFactory.getCurrentSession();
		Query query = session.getNamedQuery("Utente.findByCodiceFiscaleAndEmail")
			.setString("codiceFiscale", codiceFiscale)
			.setString("email", email);
		return (Utente)query.uniqueResult();
	}

	/**
	 * metodo che ci dice se c'è un utente registrato con un dato codice fiscale o email
	 *
	 * @param codiceFiscale
	 *            , email
	 * @return Utente
	 *
	 */
	@SuppressWarnings("unchecked")
	@Override
	public boolean isUtenteRegistrato (String codiceFiscale, String email, Integer idUtente) throws Exception{
		Session session = sessionFactory.getCurrentSession();
		Criteria criteria = session.createCriteria(Utente.class);
		criteria.add(Restrictions.isNull("dataCancellazione"));

		Criterion criterion1 = Restrictions.eq("codiceFiscale", codiceFiscale).ignoreCase();
		Criterion criterion2 = Restrictions.eq("email", email).ignoreCase();

		Criterion ORcriterion	= Restrictions.or(criterion1, criterion2);
		criteria.add(ORcriterion);

		if(idUtente!=null){

			criteria.add(Restrictions.ne("id",idUtente));
		}

		List<Utente> utentiRegistrati = criteria.list();

		return utentiRegistrati!=null&&utentiRegistrati.size()!=0?true:false;
	}

	/**
	 * metodo che ritorna un utente corrispondente ad un determinato id
	 *
	 * @param idUtente
	 *
	 */
	@Override
	public Utente getUtente(Integer idUtente) throws Exception {
		Session session = sessionFactory.getCurrentSession();
		Query query = session.getNamedQuery("Utente.findById")
			.setInteger("idUtente", idUtente);
		return (Utente)query.uniqueResult();
	}

	/**
	 *  metodo che conta quanti utenti sono associati a quel gruppo operativo
	 *
	 * @param gruppoOperativo
	 * @return
	 * @throws Exception
	 */
	@Override
	public int countUtentiForGruppoOperativo (GruppoOperativo gruppoOperativo) throws Exception{
		Session session = sessionFactory.getCurrentSession();
		Criteria criteria = session.createCriteria(Utente.class)
		.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
	    .setFetchMode("gruppiOperativi", FetchMode.JOIN);  

		criteria.createAlias("gruppiOperativi", "g",CriteriaSpecification.INNER_JOIN);
		criteria.add(Restrictions.eq("g.id", gruppoOperativo.getId()));
		criteria.add(Restrictions.isNull("dataCancellazione"));

		Number count = (Number) criteria.setProjection(Projections.rowCount()).uniqueResult();

		return count!=null?count.intValue():0;

	}

	/**
	 * metodo che aggiorna i dati di una determinata utente
	 *
	 * @param idUtente
	 *
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public boolean updateUtente(Utente utente) throws Exception {

		try{

			Session session = sessionFactory.getCurrentSession();

			utente.setDataModifica(new Date());
		    session.clear();
			session.update(utente);
			session.flush();
			//session.evict(utente);
		}
		catch(Exception e){
			log.error("UtenteDaoImpl - updateUtente: ",e);
			return false;
		}
		return true;
	}

	/**
	 * metodo per il salvataggio di una nuova utente
	 *
	 * @param utente
	 * @return
	 * @throws Exception
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public boolean saveUtente(Utente nuovoUtente) throws Exception {

		try{
			Session session = sessionFactory.getCurrentSession();
			session.clear();
			session.save(nuovoUtente);
			session.flush();
			//session.evict(nuovoUtente);
		}
		catch(Exception e){
			log.error("UtenteDaoImpl - saveUtente: ",e);
			return false;
		}
		return true;
	}
}
Spring3_SampleAnnotations
Titolo: Spring3_SampleAnnotations (0 click)
Etichetta:
Filename: spring3_sampleannotation.zip
Dimensione: 8 KB

Come sta cambiando Volunia: importanti novità dal 18 maggio 2012

In questi mesi, vi sarà sicuramente capitato di domandarvi che fine avesse fatto Volunia e, probabilmente, cosa stava nascondendo il silenzio e l’assenza di comunicazioni da parte nostra.

Questa scelta vi sarà sembrata incomprensibile, magari a tratti anche irrispettosa e poco ragguardevole nei confronti di chi ha dimostrato curiosità, interesse e partecipazione intorno al progetto. Se il nostro atteggiamento è risultato tale, o vi ha in qualche modo infastidito, vi preghiamo di accettare le nostre scuse. Chiediamo scusa soprattutto ai nostri Power User, che nonostante tutto, sono rimasti con noi, hanno continuato a scoprire, scandagliare, studiare la piattaforma di Volunia.

Ci teniamo, però, a farvi sapere che non è mai stata nostra intenzione ignorare le voci rivolte a noi o chiudere le porte ai nostri sostenitori. Abbiamo preferito, in questi mesi, rimanere momentaneamente in disparte, per osservare doviziosamente quello che stava succedendo, in seguito al lancio della prima Beta, e ascoltare con attenzione tutto ciò che ci veniva criticato, suggerito, consigliato.

Abbiamo accettato, seppur con dispiacere, anche polemiche e duri attacchi, comprendendo che erano dettati dal disappunto e dalla delusione che probabilmente questa nostra linea di azione ha contribuito ad alimentare.

Questo nostro ritiro si è tradotto, dunque, in un’approfondita attività di analisi delle criticità, che ci ha portato a comprendere, mediante un duro e scrupoloso lavoro di ricerca e implementazione, cosa migliorare, cosa modificare, cosa sostituire o integrare in Volunia.

Dal 18 maggio, infatti, i nostri Power User potranno testare con mano alcuni sostanziali cambiamenti, che consentiranno di comprendere ancora meglio l’identità, l’unicità di Volunia e le sue grandi potenzialità.

Ecco in anteprima qualche anticipazione:

  • Rafforzeremo le funzioni di ricerca attraverso l’integrazione nel sistema Volunia con uno dei principali motori di ricerca presenti sul mercato mondiale. Abbiamo deciso, pur continuando a portare avanti lo sviluppo del nostro motore, di mettere a vostra disposizione un motore di ricerca primario, per consentirvi di fruire di tutte le funzionalità di Volunia e di tutte le sue potenzialità.
  • Volunia avrà una nuova veste grafica, più funzionale e accattivante, pensata e realizzata anche grazie al Vostro contributo.
  • Metteremo a vostra disposizione documenti più chiari ed esaustivi riguardanti le politiche di privacy e i termini e condizioni di utilizzo del servizio Volunia.

E’ iniziata, dunque, la nuova fase di Volunia, agli aggiornamenti apportati il 18 maggio ne seguiranno altri, a partire dal 21 maggio.

Stiamo lavorando con solerzia per riuscire ad aprire Volunia a tutti. La nostra intenzione e la nostra speranza è di riuscire a renderlo disponibile al pubblico entro il 14 giugno. Questo tempo ci sarà utile a verificare, grazie anche al prezioso contributo dei nostri Power User, che durante questa seconda fase di Beta testing non emergano grosse criticità.

La svolta di Volunia inizia, però, in realtà, già oggi.

Questo che state leggendo, infatti, è il post inaugurale di blog.volunia, il nostro canale di comunicazione ufficiale attraverso il quale, a partire da questo momento, vi terremo al corrente di tutti i nostri passi nella crescita del progetto Volunia: le novità, il lancio ufficiale con apertura pubblica e tutte le innovazioni che apporteremo da ora in poi.

Con blog.volunia aumenteranno, oltretutto, le possibilità di interazione con voi utenti e se lo vorrete, potrete diventare parte integrante delle scelte di Volunia partecipando, per esempio, a sondaggi riguardanti la scelta di alcuni aspetti grafici, legati alle mappe visuali.

Oltre al blog, la nostra comunicazione passerà anche attraverso un servizio di newsletter e una rinnovata sezione Q&A.
Saremo sempre presenti. Sarete costantemente aggiornati e informati sugli sviluppi di Volunia e sulle tempistiche necessarie a rendere la nostra piattaforma sempre funzionale e in linea con le vostre esigenze e aspettative.

Grazie a tutti per averci aspettato.

Il Team Volunia

Mie considerazioni dopo aver letto l’articolo su Il Giornale (09 febbraio 2012):

Volunia, ma che delusione il Google made in Italy Lo abbiamo provato per voi

Debutta il motore di ricerca italiano, salutato da tutti come rivoluzionario. Il “papà”: siamo solo all’inizio, ma dovevamo mostrarci agli investitori
E’ vero, Volunia è all’inizio di una strada tutta in salita, ma con una idea eccellente. Il web è “social”? Ebbene, anche lo strumento che utilizziamo per navigarlo lo diventa. Purtroppo, il progetto nasce in un periodo non proprio roseo per la finanza mondiale. Ribadirei una cosa scontata, ossia che il grosso problema non è tanto il limite tecnologico, che si supera con il lavoro e la ricerca (cosa in cui noi Italiani siamo imbattibili), ma sono i soldi che non girano per finanziare progetti del genere.
Forse occorreva soltanto aspettare un pò prima di far uscire la versione “alfa”, tanto criticata forse immeritamente, ma con problemi evidenti (nella presentazione e nelle funzionalità).
L’articolo de Il Giornale che considera una delusione il “Google made in Italy” è per me sdegnoso per rappresentare un lavoro che nasce dalla collaborazione di una piccola equipe di studenti ed ex studenti dell’Università, dove insegna lo stesso Marchiori. Ma che ci si aspettava? Davvero di riprogettare Google da un giorno all’altro? Io premierei soprattutto l’idea brillante che, se trova a metà di quest’anno una realizzazione concreta e ben apprezzata, potrà essere un risultato straordinario per l’innovazione italiana.
Ancora una volta una idea innovativa che nasce nelle nostre Università ma che, stavolta, potrebbe essere sviluppata anche in casa nostra, invece di vedere le nostre menti geniali trovare gloria altrove.