He escrito con éxito mi primer ejemplo de hijo principal con hibernación. Después de algunos días lo tomé de nuevo y actualicé algunas bibliotecas. No estoy seguro de lo que hice, pero nunca podría hacerlo funcionar nuevamente. ¿Podría alguien ayudar a mi figura lo que está mal en el código que está regresando siguiente mensaje de error: mapeoorg.hibernate.PersistentObjectException: entidad separada pasada para persistir
org.hibernate.PersistentObjectException: detached entity passed to persist: example.forms.InvoiceItem
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:127)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:799)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:791)
.... (truncated)
de hibernación:
<hibernate-mapping package="example.forms">
<class name="Invoice" table="Invoices">
<id name="id" type="long">
<generator class="native" />
</id>
<property name="invDate" type="timestamp" />
<property name="customerId" type="int" />
<set cascade="all" inverse="true" lazy="true" name="items" order-by="id">
<key column="invoiceId" />
<one-to-many class="InvoiceItem" />
</set>
</class>
<class name="InvoiceItem" table="InvoiceItems">
<id column="id" name="itemId" type="long">
<generator class="native" />
</id>
<property name="productId" type="long" />
<property name="packname" type="string" />
<property name="quantity" type="int" />
<property name="price" type="double" />
<many-to-one class="example.forms.Invoice" column="invoiceId" name="invoice" not-null="true" />
</class>
</hibernate-mapping>
EDIT: InvoiceManager.java
class InvoiceManager {
public Long save(Invoice theInvoice) throws RemoteException {
Session session = HbmUtils.getSessionFactory().getCurrentSession();
Transaction tx = null;
Long id = null;
try {
tx = session.beginTransaction();
session.persist(theInvoice);
tx.commit();
id = theInvoice.getId();
} catch (RuntimeException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
throw new RemoteException("Invoice could not be saved");
} finally {
if (session.isOpen())
session.close();
}
return id;
}
public Invoice getInvoice(Long cid) throws RemoteException {
Session session = HbmUtils.getSessionFactory().getCurrentSession();
Transaction tx = null;
Invoice theInvoice = null;
try {
tx = session.beginTransaction();
Query q = session
.createQuery(
"from Invoice as invoice " +
"left join fetch invoice.items as invoiceItems " +
"where invoice.id = :id ")
.setReadOnly(true);
q.setParameter("id", cid);
theInvoice = (Invoice) q.uniqueResult();
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
} finally {
if (session.isOpen())
session.close();
}
return theInvoice;
}
}
factura .java
public class Invoice implements java.io.Serializable {
private Long id;
private Date invDate;
private int customerId;
private Set<InvoiceItem> items;
public Long getId() {
return id;
}
public Date getInvDate() {
return invDate;
}
public int getCustomerId() {
return customerId;
}
public Set<InvoiceItem> getItems() {
return items;
}
void setId(Long id) {
this.id = id;
}
void setInvDate(Date invDate) {
this.invDate = invDate;
}
void setCustomerId(int customerId) {
this.customerId = customerId;
}
void setItems(Set<InvoiceItem> items) {
this.items = items;
}
}
InvoiceItem.java
public class InvoiceItem implements java.io.Serializable {
private Long itemId;
private long productId;
private String packname;
private int quantity;
private double price;
private Invoice invoice;
public Long getItemId() {
return itemId;
}
public long getProductId() {
return productId;
}
public String getPackname() {
return packname;
}
public int getQuantity() {
return quantity;
}
public double getPrice() {
return price;
}
public Invoice getInvoice() {
return invoice;
}
void setItemId(Long itemId) {
this.itemId = itemId;
}
void setProductId(long productId) {
this.productId = productId;
}
void setPackname(String packname) {
this.packname = packname;
}
void setQuantity(int quantity) {
this.quantity = quantity;
}
void setPrice(double price) {
this.price = price;
}
void setInvoice(Invoice invoice) {
this.invoice = invoice;
}
}
EDIT: objeto JSON enviado desde el cliente:
{"id":null,"customerId":3,"invDate":"2005-06-07T04:00:00.000Z","items":[
{"itemId":1,"productId":1,"quantity":10,"price":100},
{"itemId":2,"productId":2,"quantity":20,"price":200},
{"itemId":3,"productId":3,"quantity":30,"price":300}]}
EDIT: Algunos detalles:
he tratado de guardar la factura siguiendo dos maneras:
fabricado manualmente mencionado anteriormente objeto json y lo pasó a la sesión de servidor reciente. En este caso absolutamente ninguna actividad se ha realizado antes de llamar método para guardar lo que no debería haber ninguna sesión abierta excepto el que se abrió en Guardar método
cargado los datos existentes mediante el uso de método getInvoice y se las pasó misma datos después de eliminar el valor clave. Esto también creo que debe cerrar la sesión antes de guardar como la transacción se está confirmando en el método getInvoice.
En ambos casos estoy consiguiendo mismo mensaje de error que me está obligando a creer que algo está mal o bien con el archivo de configuración de hibernación o clases de entidad o guardar método.
Por favor, hágamelo saber si debería proporcionar más detalles
Gracias @Alex Gitelman.He agregado algunos detalles en la parte inferior de mi pregunta original. ¿Ayuda entender mi problema? o por favor avíseme qué otros detalles serían útiles. – WSK
su referencia me ayudó a encontrar el error estúpido. Estaba enviando un valor nulo para "itemId" que es la clave principal en la tabla secundaria. Entonces hibernate estaba asumiendo que el objeto ya existe en alguna sesión. Gracias por el consejo – WSK
Ahora recibo este error: "org.hibernate.PropertyValueException: la propiedad no nula hace referencia a un valor nulo o transitorio: example.forms.InvoiceItem.invoice". ¿Podría darme alguna pista? Gracias de antemano – WSK