尝试使用JPA

时间:2015-09-02 16:37:20

标签: java sql-server flex jpa ejb

我是JPA的新手,我遇到了无法找到解决方案的问题:

我正在使用EJB和JPA来使用MySQL服务器数据库。我通过JAVA中自己制作的WebService插入数据,并从Flex应用程序调用。

我在数据库上有一个名为SiProducto的表,我存储了产品。数据库中表的定义如下:

CREATE TABLE "SiProducto" (
"Codigo_HE" VARCHAR(10) NOT NULL,
"Codigo_Producto" VARCHAR(15) NOT NULL,
"Descripcion" VARCHAR(255) NULL,
"Descripcion_Larga" VARCHAR(255) NULL,
"Codigo_Tipo_Producto" INT NULL,
"Codigo_Unidad_Medida" INT NULL,
"Codigo_Familia" INT NULL,
"Exento" TINYINT NULL,
"Ultimo_Precio_Compra" FLOAT NULL,
"Ultimo_Precio_Venta" FLOAT NULL,
"PMP" FLOAT NULL,
"Fecha_Ultima_Compra" DATETIME NULL,
"Fecha_Ultima_Venta" DATETIME NULL,
"Foto_Producto" VARCHAR(255) NULL,
"Observaciones" VARCHAR(255) NULL,
"NoValida_Stock" TINYINT NULL,
"Imagen" IMAGE NULL,
"Activo" TINYINT NULL,
"Codigo_Moneda" INT NULL,
"FechaHora" DATETIME NULL,
"Usuario" VARCHAR(50) NULL,
"Estacion" VARCHAR(50) NULL,
"FechaHora_Modifica" DATETIME NULL,
"Usuario_Modifica" VARCHAR(50) NULL,
"Estacion_Modifica" VARCHAR(50) NULL,
"Codigo_Impuesto" SMALLINT NULL,
PRIMARY KEY ("Codigo_HE", "Codigo_Producto")
);

引用它的实体类中同一个表的列的定义如下:

@Entity
@Table(name = "SiProducto", schema = "dbo", catalog = "FACEL")
public class SiProducto implements java.io.Serializable {

// Fields

private static final long serialVersionUID = 1L;
private SiProductoId id;
private SiFamilia siFamilia;
private SiUnidadesDeMedidas siUnidadesDeMedidas;
private SiMoneda siMoneda;
private SiTipoProducto siTipoProducto;
private String descripcion;
private String descripcionLarga;
private Short exento;
private Double ultimoPrecioCompra;
private Double ultimoPrecioVenta;
private Double pmp;
private Timestamp fechaUltimaCompra;
private Timestamp fechaUltimaVenta;
private String fotoProducto;
private String observaciones;
private Short noValidaStock;
private String imagen;
private Short activo;
private Timestamp fechaHora;
private String usuario;
private String estacion;
private Timestamp fechaHoraModifica;
private String usuarioModifica;
private String estacionModifica;
private Short codigoImpuesto;
private Set<VeDetallePedido> veDetallePedidos = new HashSet<VeDetallePedido>(0);
private Set<VeDetalleCotizacion> veDetalleCotizacions = new HashSet<VeDetalleCotizacion>(0);
private Set<BoExistencia> boExistencias = new HashSet<BoExistencia>(0);
//...

请注意以下属性:siFamilia,siMoneda,siTipoProducto和siUnidadesDeMedidas。它们分别是实体类SiFamilia,SiMoneda,SiTipoProducto和SiUnidadesDeMedidas的实例,并在数据库中引用它们各自相同名称的表。 表SiMoneda和SiTipoProducto在数据库中有一个简单的Integer主键,在SiProducto类中,siMoneda和siTipoProducto对象的getter和setter定义如下:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "Codigo_Moneda")
public SiMoneda getSiMoneda() {
    return this.siMoneda;
}

public void setSiMoneda(SiMoneda siMoneda) {
    this.siMoneda = siMoneda;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "Codigo_Tipo_Producto")
public SiTipoProducto getSiTipoProducto() {
    return this.siTipoProducto;
}

public void setSiTipoProducto(SiTipoProducto siTipoProducto) {
    this.siTipoProducto = siTipoProducto;
}

另一方面,表SiFamilia和SiUnidadesDeMedidas每个都有一个由一个VARCHAR列和一个INTEGER列组成的主键。 SiProducto类的siFamilia和siUnidadesDeMedidas对象的getter和setter定义如下:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumns({
        @JoinColumn(name = "Codigo_HE", referencedColumnName = "Codigo_HE", insertable = false, updatable = false),
        @JoinColumn(name = "Codigo_Familia", referencedColumnName = "Codigo_Familia", insertable = false, updatable = false) })
public SiFamilia getSiFamilia() {
    return this.siFamilia;
}

public void setSiFamilia(SiFamilia siFamilia) {
    this.siFamilia = siFamilia;
}

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumns({
        @JoinColumn(name = "Codigo_HE", referencedColumnName = "Codigo_HE", insertable =false, updatable = false),
        @JoinColumn(name = "Codigo_Unidad_Medida", referencedColumnName = "Codigo_Unidad_Medida", insertable = false, updatable = false) })
public SiUnidadesDeMedidas getSiUnidadesDeMedidas() {
    return this.siUnidadesDeMedidas;
}

调用我用于在数据库中插入SiProducto的WebService的FLEX函数如下:

public function crear():void{
            var prod:WebProductoExtended=new WebProductoExtended();
            prod.codigo=codigo2.text;
            prod.nombre=nombreProducto2.text;
            prod.precioVenta=Number(precioVenta2.text);
            prod.codFamilia=comboFamilia2.selectedItem.codigo;
            prod.codMoneda=comboMoneda2.selectedItem.codigo;
            prod.codUMedida=comboUnidad2.selectedItem.codigo;
            prod.tipoProducto=comboTipoProducto.selectedItem.codigo;
            prod.descripcionLarga=descripcionLarga.text;
            prod.observaciones=observaciones.text;
            if(activo.selected)
                prod.activo=1;
            else
                prod.activo=0;
            if(validaStock.selected)
                prod.noValidaStock=0;
            else
                prod.noValidaStock=1;
            if(exento.selected)
                prod.exento=1;
            else
                prod.exento=0;
            //This is where i invoke the WebService
            var token:AsyncToken=wSProducto.createProduct(prod, "0000100001");
            var responder:AsyncResponder=new AsyncResponder(onCreateResult, onCreateFault, "createProduct");
            token.addResponder(responder);  
        }

在数据库中创建SiProducto的WebMethod定义为:

@WebMethod()
public WEBBase createProduct(WEBProductoExtended input, String codigoHe){
    WEBBase result=new WEBBase();
    try{
        SiProducto siprod=new SiProducto();
        SiProductoId id=new SiProductoId(codigoHe, input.getCodigo());
        SiFamiliaId idFamilia=new SiFamiliaId(codigoHe, input.getCodFamilia());
        SiFamilia familia=facadeFamilia.findById(idFamilia);
        SiMoneda moneda=facadeMoneda.findById(input.getCodMoneda());
        SiUnidadesDeMedidasId idUMedida=new SiUnidadesDeMedidasId(codigoHe, input.getCodUMedida());
        SiUnidadesDeMedidas uMedida=facadeUMedida.findById(idUMedida);
        SiTipoProducto tipoProducto=facadeTipoProducto.findById(input.getTipoProducto());
        siprod.setId(id);
        siprod.setSiFamilia(familia);
        siprod.setSiMoneda(moneda);
        siprod.setSiUnidadesDeMedidas(uMedida);
        siprod.setDescripcion(input.getNombre());
        siprod.setUltimoPrecioVenta(input.getPrecioVenta());
        siprod.setSiTipoProducto(tipoProducto);
        siprod.setDescripcionLarga(input.getDescripcionLarga());
        siprod.setActivo(input.getActivo());
        siprod.setExento(input.getExento());
        siprod.setNoValidaStock(input.getNoValidaStock());
        siprod.setObservaciones(input.getObservaciones());
        siprod.setFechaHora(new Timestamp(System.currentTimeMillis()));
        facade.save(siprod);
        result.setCodigo(0);
        result.setMensaje("Registro guardado con exito");
    }catch(Exception ex){
        result.setCodigo(-1);
        result.setMensaje("Error al crear producto: " + ex.getMessage());
    }
    return result;
}

注意:&#34; Registro guardado con exito&#34; =&#34;插入成功&#34 ;; &#34;错误的crear producto&#34; =&#34;尝试插入产品时出错&#34;。

我得到了一个&#34;插入成功&#34;来自WebMethod,当我调试我要插入的SiProducto对象时,它包含我从FLEX函数发送的所有数据,但是,当我检查数据库时,新的SiProducto具有除<列>之外的所有数据 &#34; Codigo_Familia&#34;和&#34; Codigo_Unidad_Medida&#34;,这是NULL值

问题是:在给定上述条件的情况下,如何在数据库中使用JPA插入这些值?

提前致谢

编辑:在回应Chris的评论时,我试图将其更改为insertable = true,并且我得到以下异常:

15:09:24,790 ERROR [org.jboss.msc.service.fail](ServerService线程池 - 60)MSC000001:无法启动服务jboss.persistenceunit。&#34; EARPos.ear / EJBPos.jar#服务jboss.persistenceunit中的EJBPos&#34;:org.jboss.msc.service.StartException。&#34; EARPos.ear / EJBPos.jar#EJBPos&#34;:javax.persistence.PersistenceException:[PersistenceUnit:EJBPos]无法构建EntityManagerFactory     在org.jboss.as.jpa.service.PersistenceUnitServiceImpl $ 1.run(PersistenceUnitServiceImpl.java:103)     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)[rt.jar:1.7.0_21]     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)[rt.jar:1.7.0_21]     在java.lang.Thread.run(未知来源)[rt.jar:1.7.0_21]     在org.jboss.threads.JBossThread.run(JBossThread.java:122)[jboss-threads-2.1.1.Final-redhat-1.jar:2.1.1.Final-redhat-1] 引起:javax.persistence.PersistenceException:[PersistenceUnit:EJBPos]无法构建EntityManagerFactory     在org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:924)     在org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:899)     在org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:76)     在org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:200)     在org.jboss.as.jpa.service.PersistenceUnitServiceImpl.access $ 600(PersistenceUnitServiceImpl.java:57)     在org.jboss.as.jpa.service.PersistenceUnitServiceImpl $ 1.run(PersistenceUnitServiceImpl.java:99)     ......还有4个 引起:org.hibernate.MappingException:实体映射中的重复列:cl.eugcom.pos.ejb.model.SiProducto列:Codigo_HE(应使用insert =&#34; false&#34; update =&#34映射)假#34)     在org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:696)     在org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:718)     在org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:740)     在org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:493)     在org.hibernate.mapping.RootClass.validate(RootClass.java:270)     在org.hibernate.cfg.Configuration.validate(Configuration.java:1327)     在org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1789)     在org.hibernate.ejb.EntityManagerFactoryImpl。(EntityManagerFactoryImpl.java:96)     在org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)     ... 9更多

更新:我试图为siFamilia制作Codigo_HE字段,既不可插入也不可更新,字段codigo_familia可插入和可更新,我得到了这个例外:

10:44:07,618 ERROR [org.jboss.msc.service.fail](ServerService线程池 - 61)MSC000001:无法启动服务jboss.persistenceunit。&#34; EARPos.ear / EJBPos.jar#服务jboss.persistenceunit中的EJBPos&#34;:org.jboss.msc.service.StartException。&#34; EARPos.ear / EJBPos.jar#EJBPos&#34;:javax.persistence.PersistenceException:[PersistenceUnit:EJBPos]无法构建EntityManagerFactory     在org.jboss.as.jpa.service.PersistenceUnitServiceImpl $ 1.run(PersistenceUnitServiceImpl.java:103)     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)[rt.jar:1.7.0_21]     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)[rt.jar:1.7.0_21]     在java.lang.Thread.run(未知来源)[rt.jar:1.7.0_21]     在org.jboss.threads.JBossThread.run(JBossThread.java:122)[jboss-threads-2.1.1.Final-redhat-1.jar:2.1.1.Final-redhat-1] 引起:javax.persistence.PersistenceException:[PersistenceUnit:EJBPos]无法构建EntityManagerFactory     在org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:924)     在org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:899)     在org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:76)     在org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:200)     在org.jboss.as.jpa.service.PersistenceUnitServiceImpl.access $ 600(PersistenceUnitServiceImpl.java:57)     在org.jboss.as.jpa.service.PersistenceUnitServiceImpl $ 1.run(PersistenceUnitServiceImpl.java:99)     ......还有4个 引起:org.hibernate.AnnotationException:不允许在属性中混合可更新和不可更新的列:cl.eugcom.pos.ejb.model.SiProducto.siFamilia     在org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:580)     在org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:2817)     at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1728)     在org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:895)     在org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:728)     at org.hibernate.cfg.Configuration $ MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3568)     在org.hibernate.cfg.Configuration $ MetadataSourceQueue.processMetadata(Configuration.java:3522)     在org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1379)     在org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1784)     在org.hibernate.ejb.EntityManagerFactoryImpl。(EntityManagerFactoryImpl.java:96)     在org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)     ... 9更多

我仍然不理解克里斯&#39;最后一个答案(关于更改映射,因此只有一列具有可插入和可更新的外键)

已解决:我放弃了使用JPA的方式,所以我做了一些研究,并找到了在这些条件下插入数据的方法。我没有使用EntityManager类的方法保存,而是使用createNativeQuery方法和我需要执行的SQL Sentence。 Query类具有与PreparedStatement接口类似的行为,因此我在句子中放置了问号,并且我使用setParameter方法将查询的参数放在它们各自的位置上。

结果如下:

public void save2(SiProducto entity){
    LogUtil.log("saving SiProducto instance", Level.INFO, null);
    try{
        String ql="insert into SiProducto "
                + "values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        Query q=entityManager.createNativeQuery(ql);
        q.setParameter(1, entity.getId().getCodigoHe());
        q.setParameter(2, entity.getId().getCodigoProducto());
        q.setParameter(3, entity.getDescripcion());
        q.setParameter(4, entity.getDescripcionLarga());
        q.setParameter(5, entity.getSiTipoProducto().getCodigoTipoProducto());
        q.setParameter(6, entity.getSiUnidadesDeMedidas().getId().getCodigoUnidadMedida());
        q.setParameter(7, entity.getSiFamilia().getId().getCodigoFamilia());
        q.setParameter(8, entity.getExento());
        q.setParameter(9, entity.getUltimoPrecioCompra());
        q.setParameter(10, entity.getUltimoPrecioVenta());
        q.setParameter(11, entity.getPmp());
        q.setParameter(12, entity.getFechaUltimaCompra());
        q.setParameter(13, entity.getFechaUltimaVenta());
        q.setParameter(14, entity.getFotoProducto());
        q.setParameter(15, entity.getObservaciones());
        q.setParameter(16, entity.getNoValidaStock());
        q.setParameter(17, entity.getImagen());
        q.setParameter(18, entity.getActivo());
        q.setParameter(19, entity.getSiMoneda().getCodigoMoneda());
        q.setParameter(20, entity.getFechaHora());
        q.setParameter(21, entity.getUsuario());
        q.setParameter(22, entity.getEstacion());
        q.setParameter(23, entity.getFechaHoraModifica());
        q.setParameter(24, entity.getUsuarioModifica());
        q.setParameter(25, entity.getEstacionModifica());
        q.setParameter(26, entity.getCodigoImpuesto());
        q.executeUpdate();

    }catch (RuntimeException re) {
        LogUtil.log("save failed", Level.SEVERE, re);
        throw re;
    }
}

它对我有用。无论如何,谢谢大家。

0 个答案:

没有答案