我是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;
}
}
它对我有用。无论如何,谢谢大家。