IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Validateur personnalisé cause une Exception de type StackOverflow


Sujet :

Hibernate Java

  1. #1
    Candidat au Club Avatar de sidimouley
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2019
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2019
    Messages : 1
    Points : 2
    Points
    2
    Par défaut Validateur personnalisé cause une Exception de type StackOverflow
    Bonjour, je voudrai faire un ConstraintsValidator qui vérifie si un email est déja utilisé avant d'inscrire un nouveau utilisateur dans la BDD avec ConstraintsValidator d'Hibernate en utilisant @Autowired de spring pour utiliser un JPA Repository afin de faire la recherche.

    J'ai donc changer le validator factory d'Hibernate pour que Spring instancie le validateur d'e-mail afin de pouvoir utiliser l'@Autowired.
    Tout marche nikel sauf qu'on dirait que la validation se fait sans arret ce qui lève une exception de type StackOverflow.

    Note: la validation se fait automatiquement (je n'appel pas validator.validate() tout seul) vu que j'utilise un JPA Repository accessible par des appels REST (avec jquery)

    Voici le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
     
    @Getter
    @Setter
    @Entity
    @UniqueCompteEmail
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    public abstract class Compte implements Serializable, UserDetails {
     
    	private static final long serialVersionUID = -5230227676515387462L;
     
    	@Id
    	@GeneratedValue(strategy = GenerationType.SEQUENCE)
    	private Integer id;
     
    	@NotBlank
    	@NotNull
    	@Column(unique = true)
    	private String username;
     
    	@NotNull
    	@NotBlank
    	@Size(min = 6)
    	private String password;
     
    	@Email
    	@NotNull
    	@NotBlank
    	@Column(unique = true)
    	private String email;
     
    	@Override
    	public Collection<? extends GrantedAuthority> getAuthorities() {
    		return new HashSet<GrantedAuthority>();
    	}
     
    	@Override
    	public String getPassword() {
    		return this.password;
    	}
     
    	@Override
    	public String getUsername() {
    		return this.username;
    	}
     
    	@Override
    	public boolean isAccountNonExpired() {
    		return true;
    	}
     
    	@Override
    	public boolean isAccountNonLocked() {
    		return true;
    	}
     
    	@Override
    	public boolean isCredentialsNonExpired() {
    		return true;
    	}
     
    	@Override
    	public boolean isEnabled() {
    		return true;
    	}
     
    	public abstract CompteType getTypeCompte();
     
    	public abstract void setTypeCompte(CompteType typeCompte);
     
    	public static enum CompteType {
    		ETUDIANT, ADMINISTRATEUR
    	}
    }
     
    @Repository
    public interface CompteRepository extends JpaRepository<Compte, Integer> {
     
    	public Optional<Compte> findByUsername(String username);
     
    	public Optional<Compte> findByEmail(String email);
    }
     
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = UniqueCompteEmailValidator.class)
    @Target({ ElementType.TYPE })
    public @interface UniqueCompteEmail {
     
    	String message() default "{com.mssmfactory.bacsimulator.uniquecompteemail.message}";
     
    	Class<?>[] groups() default {};
     
    	Class<? extends Payload>[] payload() default {};
    }
     
    public class UniqueCompteEmailValidator implements ConstraintValidator<UniqueCompteEmail, Compte> {
     
        @Autowired
        private CompteRepository compteRepository;
     
        @Override
        public void initialize(UniqueCompteEmail constraintAnnotation) {
        }
     
        @Override
        public boolean isValid(Compte value, ConstraintValidatorContext context) {
            if (value != null) {
                Optional<Compte> compte = this.compteRepository.findByEmail(value.getEmail());
     
                return !compte.isPresent();
            } else
                return false;
        }
    }
     
    @Component
    public class ValidatorAddingCustomizer implements HibernatePropertiesCustomizer {
     
    	@Autowired
    	private ValidatorFactory validatorFactory;
     
    	public void customize(Map<String, Object> hibernateProperties) {
    		if (validatorFactory != null) {
    			hibernateProperties.put("javax.persistence.validation.factory", validatorFactory);
    		}
    	}
    }
    Merci d'avance.

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    463
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 463
    Points : 897
    Points
    897
    Billets dans le blog
    5
    Par défaut
    Je ne vois pas l'intérêt de le faire, et surtout de le faire par Hibernate Validator (qui soit dit au passage est un très bon framework).

    D'autant que si je comprends bien, tu n'utilise pas validator.validate().

    Hibernate Validator est très bien pour vérifier la cohérence intrinsèque d'un champs (Est-ce null, est-ce un mail, un ISBN ...), moins adapté pour la cohérence vis à vis d'un autre champs.

    Pour moi, 2 stratégies sont envisageable:
    1) Le faire directement dans la BDD. En résumé, explicité que le champs en BDD est unique (Marqué dans @Column(unique = true)).
    Une BDD est toujours cohérente. elle vérifiera toujours la cohérence de la donnée. Si on essaye d'insérer un email existant, la BDD enverra elle-même une exception.

    2) Le faire au sein de la DAO. Plus lourd, plus bourratif, mais permet d'avoir un traitement différentié de l'exception (pour un message d'erreur par exemple).

    On aurait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Commencer la transation
    try{
        Chercher si il y a un compte avec l'email.
        Si oui
            Jetter Mon exception
        Si non
           Sauvegarder
           COMMIT
     
    }catch(Mon exception){
        Roolback 
        Jette mon exception
    }
    Soit dit au passage, je n'aime pas trop, personnellement, les interface CRUD de Spring.
    La raison c'est qu'il n'y a pas d'exception défini.
    Or, ça peut toujours mal se passer (BDD qui tombe en passe, erreur dans ce qui est envoyé...), soit une exception à traiter.

    Le RuntimeException, c'est plutôt les erreurs de codage, donc lié au développeur.

Discussions similaires

  1. [PHP 5.3] Instance de BDD dans une classe qui cause une exception
    Par lamouche42 dans le forum Langage
    Réponses: 5
    Dernier message: 29/10/2011, 12h13
  2. Réponses: 0
    Dernier message: 03/02/2010, 14h00
  3. Réponses: 0
    Dernier message: 21/08/2007, 21h08
  4. Réponses: 3
    Dernier message: 30/03/2007, 11h57
  5. Réponses: 1
    Dernier message: 27/03/2007, 09h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo