非空属性引用空值或瞬态值

面对用hibernate保存父/子对象的麻烦。 任何想法将不胜感激。

org.hibernate.PropertyValueException: not-null property references a null or transient value: example.forms.InvoiceItem.invoice at org.hibernate.engine.Nullability.checkNullability(Nullability.java:100) .... (truncated) 

hibernate映射:

 <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> 

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; } } 

Invoice.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; } } 

由于多对一映射中的not-null="true" ,每个InvoiceItem必须附带一张Invoice

所以基本的想法是你需要在代码中build立明确的关系。 有很多方法可以做到这一点。 在你的类上,我看到一个setItems方法。 我没有看到一个addInvoiceItem方法。 当你设置项目,你需要遍历设置,并调用item.setInvoice(this)所有的项目。 如果你实现一个addItem方法,你需要做同样的事情。 或者您需要另外设置集合中每个InvoiceItem的发票。

对于追随者来说,这个错误信息也可能意味着“你有它引用一个还没有被保存到数据库的外部对象”(即使它在那里,而且是非空的)。

这可能是如此简单:

 @Column(name = "Some_Column", nullable = false) 

但是在持续的情况下,即使“Some_Column”可能不是任何主键或外键,“Some_Column”的值为空。

检查您的hbm文件中主键/对象ID的未保存值。 如果你有自动化的ID创buildhibernate框架,你设置ID的地方会引发这个错误。默认情况下,未保存的值是0,所以如果你设置ID为0,你会看到这个错误。

我得到了同样的错误,但终于解决了,实际上我没有设置已经保存到另一个实体的对象实体,因此它为foreeign键获得的对象值为null。

使该variables为transient.Your问题将得到解决..

 @Column(name="emp_name", nullable=false, length=30) private transient String empName;