Java org.hibernate.id.IdentifierGenerationException:尝试从空的一对一属性(使用session.merge)分配id

Java org.hibernate.id.IdentifierGenerationException:尝试从空的一对一属性(使用session.merge)分配id,java,hibernate,one-to-one,Java,Hibernate,One To One,我有个问题。 我的应用程序中出现错误:org.hibernate.id.IdentifierGenerationException:尝试从空的一对一属性分配id 我的波乔 用户: 用户详细信息: 表用户: 表UserDetail DAO层: 服务层 冬眠 我收到错误:org.hibernate.HibernateException:非法尝试将集合与两个打开的会话关联 所以我有4个问题: 若我理解正确的话,当userdeteil save userId from User为null时,因为user

我有个问题。 我的应用程序中出现错误:org.hibernate.id.IdentifierGenerationException:尝试从空的一对一属性分配id

我的波乔 用户:

用户详细信息:

表用户:

表UserDetail

DAO层:

服务层

冬眠

我收到错误:org.hibernate.HibernateException:非法尝试将集合与两个打开的会话关联

所以我有4个问题:

  • 若我理解正确的话,当userdeteil save userId from User为null时,因为userId并没有从表中获取icnrement Id,这是真的吗

  • 需要会话。是否在此合并

  • 如果需要合并,请说明org.hibernate.id.IdentifierGenerationException:尝试从null一对一属性分配id的正确性

  • 如果不需要合并,则“org.hibernate.HibernateException:非法尝试将集合与两个打开的会话关联”的正确性如何


  • 注意:使用merge删除是好的,使用merge创建其他实体(非User和非userdetel)是好的。

    要使其工作,请删除
    Object=session.merge(t)来自DAO类的更新方法。这里是更新方法

    @Override
    public void update(T t) throws DaoException {
            session.saveOrUpdate(t);
            log.info("Update: " + t);
    }
    
    这将修复您的
    org.hibernate.id.IdentifierGenerationException
    异常

    • 对于第1点:您的记录未保存,您正在调用merge() 方法,然后传入通过merge方法返回的对象 保存(此处)merge():将给定对象的状态复制到 具有相同标识符的持久对象。就你而言,没有 持久对象。
    • 对于第2点:此处不需要任何合并方法,请使用save或 带有会话的saveOrUpdate方法
    • 第3点:不适用
    这是一个很好的例子,我解决了我的难题。 在我的BaseDao和BaseService中,我删除了:

    private Session session = HibernateUtil.getHibernateUtil().getSession();
    
    我在BaseDao和BaseService中添加了所有方法:

    HibernateUtil.getHibernateUtil().getSession();
    
    所以我取消了两次会议 我的方法,示例create,变成了:

    @Override
    public void create(T t) throws DaoException {
            HibernateUtil.getHibernateUtil().getSession().save(t);
            log.info("Create: " + t);
    }
    

    谢谢您的回答,但如果我删除merge(t)并调用session.save(t),我会得到错误:org.hibernate.hibernateeexception:非法尝试将集合与两个打开的会话关联。也可使用marge正常保存/删除其他实体。如果我删除合并,我会得到错误:org.hibernate.HibernateException:非法尝试将集合与两个打开的会话关联。在我的帖子中,我编辑了一个错误。我想要的不是Update方法,而是write-Create方法。
    private Session session = HibernateUtil.getHibernateUtil().getSession();
    @Override
    public void create(T t) throws DaoException {
            Object object = session.merge(t);
            session.save(object);
            log.info("Update: " + t);
    }
    
    private Session session = HibernateUtil.getHibernateUtil().getSession();
    private Transaction transaction = null;
    private Dao<T> dao = new BaseDao<T>();
    @Override
    public void create(T t) throws DaoException {
        try {
            transaction = session.beginTransaction();
            dao.create(t);
            transaction.commit();
            log.info("Create: " + t);
        } catch (HibernateException e) {
            log.error("Error creating " + getPersistentClass() + " in Dao " + e);
            transaction.rollback();
            throw new DaoException(e);
        }
    }
    
    User user = new User(name, surname, email, password);
    UserDetail userDetail = new UserDetail(country, city, address);
    user.setUserDetail(userDetail);
    userDetail.setUser(user);
    userService.create(user);
    
    public class HibernateUtil {
        private static Logger log = Logger.getLogger(HibernateUtil.class);
        private static HibernateUtil util = null;
        private static SessionFactory sessionFactory = null;
        private static final ThreadLocal<Session> sessions = new ThreadLocal<Session>();
    
        private HibernateUtil() {
            try {
            Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
            log.info("Hibernate Configuration loaded");
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
            log.info("Hibernate serviceRegistry created");
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            } catch (Throwable e) {
                log.error("Initial SessionFactory creation failed. " + e);
                System.exit(0);
            }
        }
    
        public Session getSession () {
            Session session = sessions.get();
            if (session == null) {
                session = sessionFactory.openSession();
                sessions.set(session);
            } 
            return session;
        }
    
        public static synchronized HibernateUtil getHibernateUtil(){
            if (util == null){
                util = new HibernateUtil();
            }
            return util;
        }
    }
    
    @Override
    public void create(T t) throws DaoException {
            session.save(t);
            log.info("Create: " + t);
    }
    
    @Override
    public void update(T t) throws DaoException {
            session.saveOrUpdate(t);
            log.info("Update: " + t);
    }
    
    private Session session = HibernateUtil.getHibernateUtil().getSession();
    
    HibernateUtil.getHibernateUtil().getSession();
    
    @Override
    public void create(T t) throws DaoException {
            HibernateUtil.getHibernateUtil().getSession().save(t);
            log.info("Create: " + t);
    }