我正在使用Netbeans 7.4,Maven,JSF 2.2,Primefaces 5.0,Hibernate 3.6.10和Spring 3.2.3开发一个小型wab项目。

我有这些MySQL表/关系:

CREATE TABLE `usuarios` (
  `usu_nick` varchar(25) NOT NULL,
  `usu_pass` varchar(20) default NULL,
  `usu_rol` char(3) NOT NULL,
  PRIMARY KEY  (`usu_nick`),
  KEY `usu_rol` (`usu_rol`)
) ENGINE = innodb CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE `roles` (
  `rol_cod` char(3) NOT NULL,
  `rol_per` char(3) NOT NULL,
  `rol_des` varchar(25) default NULL,
  PRIMARY KEY  (`rol_cod`),
  KEY `rol_per` (`rol_per`)
) ENGINE = innodb CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE `permisos` (
  `per_cod` char(3) NOT NULL,
  `per_des` varchar(25) default NULL,
  `per_lvl` tinyint default NULL,
  PRIMARY KEY  (`per_cod`)
) ENGINE = innodb CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE `datosusu` (
  `datosusu_cod` varchar(25) NOT NULL,
  `datosusu_fecalta` date default NULL,
  `datosusu_fecbaja` date default NULL,
  `datosusu_nomfisc` varchar(100) default NULL,
  `datosusu_nomcomer` varchar(100) default NULL,
  `datosusu_nifcif` varchar(15) default NULL,
  `datosusu_contacto` varchar(100) default NULL,
  `datosusu_tlfempre` varchar(15) default NULL,
  `datosusu_tlfparti` varchar(15) default NULL,
  `datosusu_fax` varchar(15) default NULL,
  `datosusu_mailempre` varchar(50) default NULL,
  `datosusu_mailparti` varchar(50) default NULL,
  `datosusu_dir` varchar(50) default NULL,
  `datosusu_cp` varchar(5) default NULL,
  `datosusu_localidad` varchar(50) default NULL,
  `datosusu_prov` char(2) NOT NULL,
  `datosusu_zona` char(3) NOT NULL,
  `datosusu_tipo` char(3) NOT NULL,
  `datosusu_titular` varchar(100) default NULL,
  `datosusu_sucur` varchar(50) default NULL,
  `datosusu_ccc` varchar(30) default NULL,
  `datosusu_web` varchar(20) default NULL,
  `datosusu_cargo` varchar(20) default NULL,
  `datosusu_foto` varchar(100) default NULL,
  `datosusu_des` varchar(500) default NULL,
  `datosusu_lat` double default NULL,
  `datosusu_lon` double default NULL,
  PRIMARY KEY  (`datosusu_cod`),
  KEY `datosusu_prov` (`datosusu_prov`),
  KEY `datosusu_zona` (`datosusu_zona`),
  KEY `datosusu_tipo` (`datosusu_tipo`)
) ENGINE = innodb CHARACTER SET utf8 COLLATE utf8_unicode_ci;

ALTER TABLE `usuarios`
  ADD CONSTRAINT `usuarios_ibfk_1` FOREIGN KEY (`usu_rol`) REFERENCES `roles` (`rol_cod`);



ALTER TABLE `roles`
  ADD CONSTRAINT `roles_ibfk_1` FOREIGN KEY (`rol_per`) REFERENCES `permisos` (`per_cod`);



ALTER TABLE `datosusu`
  ADD CONSTRAINT `datosusu_ibfk_1` FOREIGN KEY (`datosusu_cod`) REFERENCES `usuarios` (`usu_nick`);

ALTER TABLE `datosusu`
  ADD CONSTRAINT `datosusu_ibfk_2` FOREIGN KEY (`datosusu_prov`) REFERENCES `provincias` (`prov_cod`);

ALTER TABLE `datosusu`
  ADD CONSTRAINT `datosusu_ibfk_3` FOREIGN KEY (`datosusu_zona`) REFERENCES `zonas` (`zon_cod`);

ALTER TABLE `datosusu`
  ADD CONSTRAINT `datosusu_ibfk_4` FOREIGN KEY (`datosusu_tipo`) REFERENCES `tiposnegocio` (`tiposnegocio_cod`);


这些是HBM.XNL文件:

<hibernate-mapping>
    <class name="backingbeans.Datosusu" table="datosusu" catalog="apec">
        <id name="datosusuCod" type="string">
            <column name="datosusu_cod" length="25" />
            <generator class="foreign">
                <param name="property">usuarios</param>
            </generator>
        </id>
        <many-to-one name="tiposnegocio" class="backingbeans.Tiposnegocio" fetch="select">
            <column name="datosusu_tipo" length="3" not-null="true" />
        </many-to-one>
        <many-to-one name="provincias" class="backingbeans.Provincias" fetch="select">
            <column name="datosusu_prov" length="2" not-null="true" />
        </many-to-one>
        <many-to-one name="zonas" class="backingbeans.Zonas" fetch="select">
            <column name="datosusu_zona" length="3" not-null="true" />
        </many-to-one>
        <one-to-one name="usuarios" class="backingbeans.Usuarios" constrained="true"></one-to-one>
        <property name="datosusuFecalta" type="date">
            <column name="datosusu_fecalta" length="10" />
        </property>
REST OF FIELD DEFINITIONS...

<hibernate-mapping>
    <class name="backingbeans.Usuarios" table="usuarios" catalog="apec">
        <id name="usuNick" type="string">
            <column name="usu_nick" length="25" />
            <generator class="assigned" />
        </id>
        <many-to-one name="roles" class="backingbeans.Roles" fetch="select">
            <column name="usu_rol" length="3" not-null="true" />
        </many-to-one>
        <property name="usuPass" type="string">
            <column name="usu_pass" length="20" />
        </property>
        <set name="mensajesesForSmsDest" table="mensajes" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="sms_dest" length="25" not-null="true" />
            </key>
            <one-to-many class="backingbeans.Mensajes" />
        </set>
        <one-to-one name="datosusu" class="backingbeans.Datosusu"></one-to-one>
        <set name="mensajesesForSmsUsu" table="mensajes" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="sms_usu" length="25" not-null="true" />
            </key>
            <one-to-many class="backingbeans.Mensajes" />
        </set>
    </class>
</hibernate-mapping>


当我尝试创建新的User-DatosUsu时出现问题。当在Web视图中满足所有数据时,我在Spring Web服务中调用2个函数来保存它们:

    public void setNuevoUsuario(Usuarios elUsuario){

    Session sesion=HibernateUtil.getSessionFactory().openSession();
    try {
        sesion.beginTransaction();
        sesion.saveOrUpdate((Usuarios)sesion.merge(elUsuario));
        sesion.getTransaction().commit();
        sesion.close();
    }
     catch (HibernateException he) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error salvando el USUARIO.", null));
        sesion.getTransaction().rollback();
        sesion.close();
        }
    }


public void setNuevoDatosUsu(Datosusu losDatosUsu){

    Session sesion=HibernateUtil.getSessionFactory().openSession();
    try {
        sesion.beginTransaction();
        Datosusu datosTemp=(Datosusu)sesion.merge(losDatosUsu);
        sesion.saveOrUpdate(datosTemp);
        sesion.getTransaction().commit();
        sesion.close();
    }
     catch (HibernateException he) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error salvando los DATOSUSU.", null));
        sesion.getTransaction().rollback();
        sesion.close();
        }
    }


2个Hibernate对象是分离的,所以这就是我合并它们的原因。
当我尝试执行上述代码时,用户已正确插入数据库中。
但是,当我尝试插入Datosusu时,会发生此错误:

javax.faces.el.EvaluationException: org.hibernate.AssertionFailure: null identifier
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.hibernate.AssertionFailure: null identifier
    at org.hibernate.engine.EntityKey.<init>(EntityKey.java:61)
    at org.hibernate.type.OneToOneType.isNull(OneToOneType.java:77)
    at org.hibernate.type.EntityType.resolve(EntityType.java:433)
    at org.hibernate.type.EntityType.replace(EntityType.java:298)
    at org.hibernate.type.AbstractType.replace(AbstractType.java:176)
    at org.hibernate.type.TypeHelper.replace(TypeHelper.java:212)
    at org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:600)
    at org.hibernate.event.def.DefaultMergeEventListener.mergeTransientEntity(DefaultMergeEventListener.java:337)
    at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:303)
    at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:464)
    at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:255)
    at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:84)
    at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:867)
    at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:851)
    at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:855)
    at backingbeans.ServicioImpl.setNuevoDatosUsu(ServicioImpl.java:254)
    at backingbeans.AltaBB.salvaUsuario(AltaBB.java:106)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at     javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    ... 27 more


这是调用保存数据的两个过程的过程:

 public String salvaUsuario() {

        //fulfill the user with rest of fields
        elUsuario.setRoles(new Roles("NOR", new Permisos("NOR")));

        //fulfill rest of fields of losDatos
        losDatos.setProvincias(new Provincias(elPais));
        losDatos.setZonas(new Zonas(laZona));
        losDatos.setTiposnegocio(new Tiposnegocio(elTipoNegocio));
        losDatos.setDatosusuFecbaja(null);
        losDatos.setDatosusuFecalta(new Date());
        losDatos.setDatosusuCod(elUsuario.getUsuNick());

        //fulfill references
        losDatos.setUsuarios(elUsuario);
        elUsuario.setDatosusu(losDatos);

        //save both
        elServicio.setNuevoUsuario(elUsuario);
        elServicio.setNuevoDatosUsu(losDatos);

        return "login";
    }


我不明白为什么会这样。就我而言,所有数据均已正确实现。我是Hibernate的初学者。
有更多经验的人可以帮助我解决这个问题吗?
提前致谢!!!

最佳答案

好吧,终于我找到了。
我的代码唯一的问题是这些行:

Datosusu datosTemp =(Datosusu)sesion.merge(losDatosUsu);
sesion.saveOrUpdate(datosTemp);

相反,我使用了:

sesion.persist(losDatosUsu);

有人可以解释一下合并与持久之间的区别吗?
谢谢!

09-26 23:06