Неправильная функция Hibernate HQL / DAO / при кодировании Spring Security-Annotations

Я изучаю Hibernate framework, и я так путаю с сгенерированным sql.
У меня есть следующий код:

Таблица:

CREATE TABLE users (
 user_id int NOT NULL AUTO_INCREMENT,
 login varchar(20) UNIQUE,
 pass varchar(20),
 user_name varchar(20),
 surname varchar(20),
 PRIMARY KEY (user_id)
)

Модель:

@Entity
 @Table(name="users", catalog="maximodb")
 public class User implements Serializable{

@Id
@Column(name="user_id")
@GeneratedValue(strategy =GenerationType.IDENTITY)
private Integer userId;

@Column(name = "login", unique = true, length = 20)
private String login;

@Column(name = "pass", length = 20)
private String pass;

@Column(name = "user_name", length = 20)
private String userName;

@Column(name = "surname", length = 20)
private String surname;


@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "users_roles", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
private Set<Role> userRoles = new HashSet<Role>();

public User() {
}

public User(String login, String pass, String userName, String surname) {
    this.login = login;
    this.pass = pass;
    this.userName = userName;
    this.surname = surname;
}


public Integer getUserId() {
    return this.userId;
}

public void setUserId(Integer userId) {
    this.userId = userId;
}

public String getLogin() {
    return this.login;
}

public void setLogin(String login) {
    this.login = login;
}

public String getPass() {
    return this.pass;
}

public void setPass(String pass) {
    this.pass = pass;
}

public String getUserName() {
    return this.userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getSurname() {
    return this.surname;
}

public void setSurname(String surname) {
    this.surname = surname;
}

public Set<Role> getUserRoles() {
    return userRoles;
}

public void setUserRoles(Set<Role> userRoles) {
    this.userRoles = userRoles;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((login == null) ? 0 : login.hashCode());
    result = prime * result + ((pass == null) ? 0 : pass.hashCode());
    result = prime * result + ((surname == null) ? 0 : surname.hashCode());
    result = prime * result + ((userId == null) ? 0 : userId.hashCode());
    result = prime * result + ((userName == null) ? 0 : userName.hashCode());
    result = prime * result + ((userRoles == null) ? 0 : userRoles.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;
    User other = (User) obj;
    if (login == null) {
        if (other.login != null)
            return false;
    } else if (!login.equals(other.login))
        return false;
    if (pass == null) {
        if (other.pass != null)
            return false;
    } else if (!pass.equals(other.pass))
        return false;
    if (surname == null) {
        if (other.surname != null)
            return false;
    } else if (!surname.equals(other.surname))
        return false;
    if (userId == null) {
        if (other.userId != null)
            return false;
    } else if (!userId.equals(other.userId))
        return false;
    if (userName == null) {
        if (other.userName != null)
            return false;
    } else if (!userName.equals(other.userName))
        return false;
    if (userRoles == null) {
        if (other.userRoles != null)
            return false;
    } else if (!userRoles.equals(other.userRoles))
        return false;
    return true;
}

}

А теперь….. функция dao (два варианта):

Первый:

List<User> users = new ArrayList<User>();

    users = sessionFactory.getCurrentSession()
        .createQuery("from User where login= :login")
        .setString( "login", login )
        .list();

    if (users.size() > 0) {
        return users.get(0);
    } else {
        return null;
    }

Возвращенный sql:

select
    user0_.user_id as user_id1_1_,
    user0_.login as login2_1_,
    user0_.pass as pass3_1_,
    user0_.surname as surname4_1_,
    user0_.user_name as user_nam5_1_ 
from
    maximodb.users user0_ 
where
    user0_.login=?

И второй вариант:

    Criteria criteria =  sessionFactory.getCurrentSession().createCriteria(User.class);
    List<User> a = (List<User>) criteria.list();

User us = a.get(0);


    return us;

Возвращенный sql:

select
    this_.user_id as user_id1_1_0_,
    this_.login as login2_1_0_,
    this_.pass as pass3_1_0_,
    this_.surname as surname4_1_0_,
    this_.user_name as user_nam5_1_0_ 
from
    maximodb.users this_

Второй вариант вполне корректен и получает пользователя из БД. Но в первом случае вместо объекта User существует исключение null pointer. Что неверно?
Стоит отметить, что сгенерированный sql хорошо работает в MySQL Workbench (первый случай).

1 ответ

  1. Первый вариант пытается получить пользователя с заданным логином, но для этого логина не найден пользователь (убедитесь, что в базе данных есть пользователь с заданным логином).
    Второй вариант перечисляет всех пользователей в базе данных и чем получить первый. Таблица пользователя содержит несколько пользователей, поэтому этот вариант возвращает пользователя, а не null.