-1

I am having a problem with the following code

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loginController' defined in file [C:\Users\USERNAME\IdeaProjects...\application\ui\security\controller\LoginController.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loginServiceImpl' defined in file [C:\Users\USERNAME\IdeaProjects\...\core\domain\login\LoginServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginRepository' defined in be.mypackage.core.persistence.LoginRepository defined in @EnableJpaRepositories declared on DomainConfig: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List be.mypackage.core.persistence.LoginRepository.findListIdentifiant()!

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loginServiceImpl' defined in file [C:\Users\USERNAME\IdeaProjects\....\core\domain\login\LoginServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginRepository' defined in be.mypackage.core.persistence.LoginRepository defined in @EnableJpaRepositories declared on DomainConfig: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List be.mypackage.core.persistence.LoginRepository.findListIdentifiant()!

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginRepository' defined in be.mypackage.core.persistence.LoginRepository defined in @EnableJpaRepositories declared on DomainConfig: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List be.mypackage.core.persistence.LoginRepository.findListIdentifiant()!

Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List be.mypackage.core.persistence.LoginRepository.findListIdentifiant()!


Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.IdentNode 
 \-[IDENT] IdentNode: 'loginRole' {originalText=loginRole}


Caused by: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.IdentNode 
 \-[IDENT] IdentNode: 'loginRole' {originalText=loginRole}

I'm trying to retrieve some value from the table but not all of it. And I have this error. I don't want to use @Transient because it prevents me from retrieving the password value at another time.

the problem seems to be with the enum field, if I remove it from the query, with an appropriate constructor, the query no longer returns an error when launching the program.

There must be something simple that I'm not doing right.

my request jpa

import be.mypackage.core.domain.login.Login;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.data.jpa.repository.Query;


import java.util.List;



public interface LoginRepository extends JpaRepository<Login, Integer> {

@Query(value = "SELECT idLogin, identifiant, societe, loginRole FROM Login")

List<Login> findListIdentifiant();

}

My Class entity Login

package be.mypackage.core.domain.login;

import be.mypackage.core.domain.societe.Societe;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.PrePersist;
import javax.persistence.Transient;

@Entity
@SQLDelete(sql = "UPDATE login SET status_actif = false WHERE id_login=?")
@Where(clause = "status_actif <> 'false'")
public class Login {

    @Id
    @Column(nullable = false, updatable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer idLogin;

    @Column(length = 100, unique = true)
    private String identifiant;

    //@Transient
    @Column(length = 100)
    private String motDePasse;

    @ManyToOne(fetch = FetchType.LAZY) // OK
    @JoinColumn(name = "no_societe", nullable = false)
    private Societe societe;

    @Transient
    @Column(name = "status_actif", nullable = false)
    private Boolean statusActif;

    @PrePersist
    public void fixStatusActif() {
        this.statusActif = true;
    }

    @Enumerated(EnumType.STRING)
    @Column(name = "role", unique = true, length = 30)
    private LoginRole loginRole;

    public Login() {
    }

    // jpa request work with this constructor
    public Login(Integer idLogin, String identifiant, Societe societe) {
        this.idLogin = idLogin;
        this.identifiant = identifiant;
        this.societe = societe;
    }

    // not work
    public Login(Integer idLogin, String identifiant, Societe societe, LoginRole loginRole) {
        this.idLogin = idLogin;
        this.identifiant = identifiant;
        this.societe = societe;
        this.loginRole = loginRole;
    }

    public Integer getIdLogin() {
        return idLogin;
    }

    public void setIdLogin(Integer idLogin) {
        this.idLogin = idLogin;
    }

    public String getIdentifiant() {
        return identifiant;
    }

    public void setIdentifiant(String identifiant) {
        this.identifiant = identifiant;
    }

    public String getMotDePasse() {
        return motDePasse;
    }

    public void setMotDePasse(String motDePasse) {
        this.motDePasse = motDePasse;
    }

    public Boolean getStatusActif() {
        return statusActif;
    }

    public void setStatusActif(Boolean statusActif) {
        this.statusActif = statusActif;
    }

    public Societe getSociete() {
        return societe;
    }

    public void setSociete(Societe societe) {
        this.societe = societe;
    }

    public LoginRole getLoginRole() {
        return loginRole;
    }

    public void setLoginRole(LoginRole loginRole) {
        this.loginRole = loginRole;
    }

    @Override
    public String toString() {
        return identifiant;
    }
}


Class Enum

package be.mypackage.core.domain.login;


public enum LoginRole {

    
    ROLE_ADMIN,
    
    ROLE_MANAGER,
    
    ROLE_EMPLOYEE,
    
    ROLE_EMPLOYEE_READ;


}



my table login enter image description here


findAll query works fine with enum but I can't exclude password from query

enter image description here

enter image description here

as you can see the role (enum) field is well getter with findAll but does not meet my security requirements

Abneco
  • 101
  • 1
  • 8

1 Answers1

1

You don't have to list the attributes in the query:

@Query(value = "SELECT idLogin, identifiant, societe, loginRole FROM Login")
List<Login> findListIdentifiant();

Change to:

@Query(value = "SELECT l FROM Login l")
List<Login> findListIdentifiant();

But this query is superfluous at all because there is a findAll() method on JpaRepository that does exactly does that.

Simon Martinelli
  • 34,053
  • 5
  • 48
  • 82
  • findAll query works fine with enum but I can't exclude password from query (see pictures in the post) – Abneco Apr 27 '21 at 15:42
  • And this is a problem? I mean isn't the password encrypted? And if you want to return it in a REST API you can add @JsonIgnore to exclude it from serialization – Simon Martinelli Apr 27 '21 at 15:45
  • No, the password is not encrypted, this is part of the manager's requirements ... To recover the application password. (Yes that is not very good) But your remark is not bad, I will submit it to my manager. – Abneco Apr 27 '21 at 16:03
  • Moreover this is a swing app. Isn't there a way to get an enum with jpa? (Yet he says this is supported since version 2.1) – Abneco Apr 27 '21 at 16:04
  • 1
    The problem is you cannot load partial entities. But you could create a regular class with a constructor that takes all the attributes. Do you know how constructor expression works? – Simon Martinelli Apr 27 '21 at 17:01
  • i don't speak english very well but i guess talking to you about DTO, i just recreated this but it looks like there was an error the first time i used it so i had to give up. But it seems that the solution was there, it works. – Abneco Apr 27 '21 at 18:14
  • ```@Query(value = "SELECT NEW be.mypackage.core.dto.LoginDTO (l.idLogin, l.identifiant, l.societe, l.loginRole) FROM Login l")
List findListIdentifiant();``` – Abneco Apr 27 '21 at 18:15
  • ```Hibernate: select login0_.id_login as col_0_0_, login0_.identifiant as col_1_0_, login0_.no_societe as col_2_0_, login0_.role as col_3_0_ from login login0_ inner join societe societe1_ on login0_.no_societe=societe1_.id_societe where ( login0_.status_actif <> 'false' )``` – Abneco Apr 27 '21 at 18:16
  • I mark this as resolved, thanks for helping me find my error in my code. – Abneco Apr 27 '21 at 18:18