在Hibernate测试中抛出了意外的NullPointerException

时间:2014-01-27 18:42:05

标签: java spring hibernate frameworks nullpointerexception

在项目内创建了ORM模型并编写了测试。一切都很好,直到模特没有改变。添加了一对一关系,之后测试变为返回NullPointerException。

在cutted代码中有两个类具有一对一关系。

班级护照:

@Entity
@Table(name = "PASSPORTS")
public class Passport extends BaseObject implements Serializable {

   private User user;
   private String firstName, lastName;

   // other fields...

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn (name="USER_ID", updatable = false, insertable = false)
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Column(name = "FIRST_NAME", length = 60)
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Column(name = "LAST_NAME", length = 80)
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    // other getters-setters...
}

类用户:

@Entity
@Indexed
@Table(name = "USERS")
public class User extends BaseObject implements Serializable, UserDetails {

private Passport passport;
private Long id;

// other fields...

@Id
@SequenceGenerator(name = "USERS_SEQ", sequenceName = "USERS_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_SEQ")
@Column(name = "USER_ID")
public Long getId() {
    return this.id;
}



@OneToOne(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL)
public Passport getPassport() {
    return this.passport;
}

public void setPassport(Passport passport) {
    this.passport = passport;
}


public void setId(Long id) {
    this.id = id;
} 

@Transient
public String getFirstName() {
    return getPassport().getFirstName();
}

@Transient
public String getLastName() {
    return getPassport().getLastName();
}

@Transient
public String getFullName() {
    return getPassport().getFirstName() + " " + getPassport().getLastName();
}

@Transient
public String getMiddleName() {
    return getPassport().getMiddleName();
}

@Transient
public void setFirstName(String name) {
    getPassport().setFirstName(name);
}

@Transient
public void setLastName(String name) {
    getPassport().setLastName(name);
}

@Transient
public void setMiddleName(String name) {
    getPassport().setMiddleName(name);
}

// other getters-setters...

}

现在测试:

public class UserDaoTest extends BaseDaoTestCase {
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;


@Test(expected = HibernateSystemException.class)
public void testUpdateUser() throws Exception {
    User user = userDao.get(-1L);

    Address address = user.getAddress();

    userDao.saveUser(user);
    flush();

    user = userDao.get(-1L);
    assertEquals(address, user.getAddress());

    User user2 = new User();
    user2.setAddress(user.getAddress());
    user2.setConfirmPassword(user.getConfirmPassword());
    user2.setEmail(user.getEmail());
    user2.setFirstName(user.getFirstName());
    user2.setLastName(user.getLastName());
    user2.setPassword(user.getPassword());
    user2.setPasswordHint(user.getPasswordHint());
    user2.setRoles(user.getRoles());
    user2.setUsername(user.getUsername());

    userDao.saveUser(user2);
}

@Test(expected = DataAccessException.class)
public void testAddAndRemoveUser() throws Exception {
    User user = new User("testuser");
    user.setPassword("testpass");
    user.setFirstName("Test");
    user.setLastName("Last");
    Address address = new Address();
    user.setAddress(address);
    user.setEmail("testuser@appfuse.org");

    Role role = roleDao.getRoleByName(Constants.USER_ROLE);
    assertNotNull(role.getId());
    user.addRole(role);

    user = userDao.saveUser(user);
    flush();

    assertNotNull(user.getId());
    user = userDao.get(user.getId());
    assertEquals("testpass", user.getPassword());

    userDao.remove(user);
    flush();

    // should throw DataAccessException
    userDao.get(user.getId());
}
}

测试结果:

  testUpdateUser(uz.eopc.dao.UserDaoTest): Unexpected exception, expected<org.springframework.orm.hibernate4.HibernateSystemException> but was<java.lang.NullPointerException>
  testAddAndRemoveUser(uz.eopc.dao.UserDaoTest): Unexpected exception, expected<org.springframework.dao.DataAccessException> but was<java.lang.NullPointerException>
  testAddAndRemoveUser(uz.eopc.service.impl.UserManagerImplTest): Unexpected exception, expected<org.apache.commons.beanutils.NestedNullException> but was<java.lang.reflect.InvocationTargetException>
  testAddExistingUser(uz.eopc.service.UserExistsExceptionTest): Unexpected exception, expected<uz.eopc.service.UserExistsException> but was<org.springframework.beans.FatalBeanException>
  testAddAndRemoveUser(uz.eopc.service.UserManagerTest): Unexpected exception, expected<org.apache.commons.beanutils.NestedNullException> but was<java.lang.reflect.InvocationTargetException>

似乎一对一的关系不起作用,我不知道为什么。

是的,项目使用Spring Framework,但如果我在没有Spring的情况下运行此代码,代码可以正常运行,没有任何异常。

很抱歉,我希望有人可以帮助我。

P上。 S上。

Spring Framework版本 4.0.0.RELEASE

Hibernate版本 4.2.7.FINAL

2 个答案:

答案 0 :(得分:0)

我的猜测会改变:

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn (name="USER_ID", updatable = false, insertable = false)
public User getUser() {
    return user;
}

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn (name="USER_ID")
public User getUser() {
    return user;
}

用户连接表应该是可插入和可更新的。否则,您将无法在连接列中更新或插入。这可能是个问题。 希望它有所帮助。

答案 1 :(得分:0)

最后我发现了异常的原因。我使用AppFuse Application Framework,它对模型和测试类提出了特殊要求。必须创建特殊的DAO类才能访问hibernate会话,然后才能从DB获取数据。发生异常是因为我的Passport类无法直接访问会话。