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;
}
}