2个对象相互依赖。现在怎么办?

时间:2018-04-16 08:56:19

标签: java hibernate

我做了这个简单的Spring Security教程。 https://www.boraji.com/spring-mvc-5-spring-security-5-hibernate-5-example

现在我想在我的数据库中创建一个用户。

问题在于我需要创建两个彼此依赖的对象,我得到了

  

org.hibernate.TransientObjectException:object引用未保存的瞬态实例 - 在查询刷新之前保存瞬态实例:

那么解决方案是什么?

  public static boolean createUser(byte[] image, String name, String username, String password, String permissions) {
    String hashedPassword = new BCryptPasswordEncoder().encode(password);
    //check if user already exists
    boolean exists = User.checkIfUserExists(username);
    //if it doesn't add to database
    if(!exists) {
        UserRole userRole = new UserRole();
        User user = new User();
        userRole.setRole(permissions);
        userRole.setUser(user);
        Database.addToDatabase(userRole);
        //user table
        user = new User(image, name, username, true, hashedPassword, userRole);
        Database.addToDatabase(user);
        //user role table
        userRole.setUser(user);
        Database.updateObject(userRole);

        return true;
    }
    else
        return false;
}

//Save the object to the database
public static void addToDatabase(Object object) {
    SessionFactory factory = HibernateUtil.GetSessionFactory();
    Session session = factory.openSession();
    Transaction tx = null;
    try{
        tx = session.beginTransaction();
        session.save(object);
        tx.commit();
    }catch (HibernateException e) {
        if (tx!=null) tx.rollback();
        e.printStackTrace();
    }finally {
        session.close();
    }
}

基本上UserRole已经需要在db中保存用户和用户需要在db中以保存UserRole。

1 个答案:

答案 0 :(得分:0)

该异常意味着所写的内容。你有两个对象之间的关系。例如,UserRole具有链接的用户。但是当您尝试将UserRole保存到数据库中时,您附加到它的User对象尚未保存(它处于临时状态),因此Hibernate的问题是如何在数据库中保存该用户角色用户可能不存在(它在数据库中仍然没有有效的ID)。

有不同的方法可以解决这个问题。其中之一是将列表标记为Cascade = ALL(或Cascade = SAVE_UPDATE)。这样您就可以绑定这两个对象,当您保存用户时,它将自动保存用户角色。这有利有弊。 " +"这是更容易,你将只有一个保存。 " - "是你连接了这些对象,如果不小心你可能会错误地保存/更新对象。

另一种解决方案是首先保存用户(没有角色)。然后将用户设置的角色保存到新保存的用户(它应该在数据库中有一个真实的ID)。然后将角色添加到用户并更新它。这样你就不会保存任何具有瞬态值的东西,你会解决这个问题。也可以在交易中进行,这样如果出现问题,您就不会有错误的数据。