2011-06-17 8 views
51

Problemy napotykane podczas zapisywania obiektu nadrzędnego/podrzędnego ze stanu hibernacji. Każdy pomysł byłby bardzo ceniony.Właściwość not-null odwołuje się do wartości pustej lub przejściowej

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) 

hibernacji mapowanie:

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

Odpowiedz

28

Każdy InvoiceItem musi mieć Invoice dołączone do niego ze względu na not-null="true" w wiele-do-jednego mapowania.

Więc podstawową ideą jest to, że musisz ustawić tę jawną relację w kodzie. Jest na to wiele sposobów. Na twojej klasie widzę metodę setItems. NIE widzę metody addInvoiceItem. Podczas ustawiania elementów należy przechodzić przez zestaw i wywoływać item.setInvoice(this) we wszystkich elementach. Jeśli zastosujesz metodę addItem, musisz zrobić to samo. Lub musisz inaczej ustawić fakturę każdego InvoiceItem w kolekcji.

59

dla obserwujących, ten komunikat o błędzie może również oznaczać "masz odniesienie do obcego obiektu, który nie został jeszcze zapisany do DB" (mimo że jest tam i nie jest pusty).

+0

i jak mogę rozwiązać ten problem? Przykład: Mam Entity_A z kolumna Entity_B, aw Entity_B Mam Entity_A kolumna relacji jest @OneToMany od A do B i kiedy próbuję zaktualizować Entity_A następnie daje mi ten wyjątek, w jaki sposób można zaktualizować Entity_A? – FAndrew

+0

@FAndrew zapisać Entity_B pierwszy? – rogerdpack

+2

i jeśli mam na przykład 100 Entity_B, wyszukuję wszystkie edytowane Entity_B i czy były one edytowane, aktualizuję je? Czy nie byłoby lepiej, gdybym tylko zaktualizował Entity_A? – FAndrew

2

Sprawdź niezapisane wartości klucza podstawowego/ID obiektu w plikach hbm. Jeśli masz zautomatyzowane tworzenie identyfikatorów przez platformę hibernacji i ustawiasz identyfikator gdzieś, to wyrzucisz ten błąd. Domyślnie niezapisana wartość wynosi 0, więc jeśli ustawisz identyfikator na 0, zobaczysz ten błąd.

0

Otrzymałem ten sam błąd, ale ostatecznie go rozwiązałem, w rzeczywistości nie ustawiłem obiektu obiektu, który jest już zapisany w drugim obiekcie, a tym samym wartość obiektu, który otrzymywał dla klawisza foreeign, była zerowa.

3

To może być tak proste, jak:

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

ale jednocześnie utrzymującej wartość „Some_Column” jest null, nawet jeśli „Some_Column” nie może być dowolny klucz podstawowy lub obcy.

-7

sprawi że zmienna jako problemu transient.Your dostanie rozwiązany ..

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

Mówisz o rozwiązaniu problemu i nie rozwiązaniu problemu. –

Powiązane problemy