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

Posted

技术标签:

【中文标题】Hibernate/JPA @OneToOne 返回空指针异常【英文标题】:Hibernate/JPA @OneToOne Returning Null Pointer Exception 【发布时间】:2012-06-05 20:53:09 【问题描述】:

基本堆栈: 使用 Glassfish 的 Spring/Spring Security/Hibernate

试图连接两个表中的两列,但没有返回数据。代码编译和部署没有问题。执行时,CustomUserDetailsService 尝试检索 role,我得到以下信息:

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

error 中引用的行位于try 块的Return 语句中。 特别是 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;
    


【问题讨论】:

您能否检查您的数据库以查看帐户表中是否有该帐户实际上具有关联的角色?在这个答案***.com/a/5909901/145392 中检查双向 onetoone 是如何完成的 谢谢,我想我已经盯着代码太久了......非常感谢帮助。 那是什么?没有关联角色或您更改了 oneToOne 映射? 没有关联的角色。 oneToOne 映射有效。再次感谢。 【参考方案1】:

上述配置有效。代码不起作用,因为没有与我正在测试的用户关联的角色。

【讨论】:

以上是关于Hibernate/JPA @OneToOne 返回空指针异常的主要内容,如果未能解决你的问题,请参考以下文章

hibernate/jpa double OneToOne 与一个实体的双向关系

休眠 | Spring Data JPA | @OneToOne

hibernate.jpa.criteria.BasicPathUsageException:无法加入基本类型的属性

hibernate jpa 报错

Spring Hibernate JPA 联表查询

Spring Hibernate JPA 联表查询 复杂查询