Hibernate / JPA @OneToOne返回空指针异常

时间:2012-05-31 15:10:53

标签: hibernate jpa spring-security hibernate-mapping

基本堆栈: Spring / Spring安全/ Hibernate与Glassfish

尝试在两个表中连接两列,但不返回数据。代码编译和部署没有问题。执行时,CustomUserDetailsService会尝试检索role并获得以下内容:

Caused by: java.lang.RuntimeException: java.lang.NullPointerException
    at com.bossmop.service.user.CustomUserDetailsService.loadUserByUsername(CustomUserDetailsService.java:68) ~[CustomUserDetailsService.class:na]

错误中引用的行位于Return块的try语句中。 特别是 getAuthorities(accountUser.getRole()。getRole()))

CUSTOMUSERDETAILSSERVICE

@Service("userDetailsService")
@Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {

protected static Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);

@Autowired
private IAccountDAO accountDAO;

@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {

    logger.info("CustomUserDetailService.loadUserByUsername");
    logger.debug("username: ", username);

    try {
        Account accountUser = accountDAO.findUserByUsername(username);

        logger.debug("returnfrom AccountDAO.findUserByUsername");
        logger.debug("accountUser.email: " + accountUser.getEmail());
        logger.debug("accountUser.role: " + accountUser.getRole().getRole());
        boolean enabled=true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        // TODO Generate variable columns in database
        return new User(
                accountUser.getUsername(),
                accountUser.getPassword(),
                enabled,
                accountNonExpired,
                credentialsNonExpired,
                accountNonLocked,
                getAuthorities(accountUser.getRole().getRole()));

    } catch (Exception e) {
        // TODO  handle exception
        logger.debug("exception in CustomUserDetailService");
        logger.debug("EXCEPTION: " + e);
        throw new RuntimeException(e);
    }
}

表关系为:USERS primary_key(user_id) = ROLE(fk_user_id)

模型1:用户

// Import statements...

@Entity
@Table(name="users")
public class Account {

private int id;
private String forename;
private String surname;
private String username;
private String password;
private String email;
private Date birthdate;

private Role role;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="user_id", unique=true, nullable=false)
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}

@Column(name="forename")
public String getForename() {
    return forename;
}
public void setForename(String forename) {
    this.forename = forename;
}

@Column(name="surname")
public String getSurname() {
    return surname;
}
public void setSurname(String surname) {
    this.surname = surname;
}

@Column(name="username",unique=true,nullable=false)
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}

@Column(name="password",nullable=false)
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}

@Column(name="email",unique=true,nullable=false)
public String getEmail() {
    return email;
}
public void setEmail(String email) {
    this.email = email;
}

@Column(name="birthdate")
public Date getBirthdate() {
    return birthdate;
}
public void setBirthdate(Date birthdate) {
    this.birthdate = birthdate;
}

@OneToOne(mappedBy="account", fetch=FetchType.LAZY, cascade={CascadeType.ALL})
public Role getRole() {
    return role;
}
public void setRole(Role role) {
    this.role = role;
}

@Override
public String toString() {
    StringBuffer strBuff = new StringBuffer();
    strBuff.append("id: ").append(getId());
    strBuff.append("username: ").append(getUsername());
    strBuff.append("email: ").append(getEmail());
    return strBuff.toString();
}
}

模型2:角色

@Entity
@Table(name="role")
public class Role {

    private int id;
    private int role;

    private Account account;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="role_id", unique=true, nullable=false)
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @Column(name="role", nullable=false)
    public int getRole() {
        return role;
    }
    public void setRole(int role) {
        this.role = role;
    }

    @OneToOne
    @JoinColumn(name="user_id", referencedColumnName="user_id", nullable=false)
    public Account getAccount() {
        return account;
    }

    public void setAccount(Account account) {
        this.account = account;
    }

}

1 个答案:

答案 0 :(得分:0)

以上配置有效。代码无效,因为没有与我正在测试的用户相关联的角色。