thuộc tính not-null tham chiếu đến giá trị null hoặc tạm thời


81

Đối mặt với rắc rối trong việc lưu đối tượng cha / con với chế độ ngủ đông. Bất kỳ ý tưởng sẽ được đánh giá cao.

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)

lập bản đồ ngủ đông:

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

Câu trả lời:


47

Mỗi InvoiceItemphải có Invoicegắn liền với nó vì not-null="true"trong nhiều-một bản đồ.

Vì vậy, ý tưởng cơ bản là bạn cần thiết lập mối quan hệ rõ ràng đó trong mã. Có nhiều cách để làm điều đó. Trên lớp học của bạn, tôi thấy một setItemsphương pháp. Tôi KHÔNG thấy một addInvoiceItemphương pháp. Khi bạn đặt các mục, bạn cần phải lặp qua nhóm và gọi item.setInvoice(this)trên tất cả các mục. Nếu bạn triển khai một addItemphương pháp, bạn cần phải làm điều tương tự. Hoặc bạn cần phải đặt Hóa đơn của mọi người InvoiceItemtrong bộ sưu tập.


80

đối với những người theo dõi, thông báo lỗi này cũng có thể có nghĩa là "bạn có nó tham chiếu đến một đối tượng nước ngoài chưa được lưu vào DB" (mặc dù nó ở đó và không phải là null).


1
Và làm thế nào tôi có thể giải quyết điều này? Ví dụ: Tôi có Entity_A với cột Entity_B và trong Entity_B tôi có cột Entity_A, quan hệ là @OneToMany từ A đến B và khi tôi cố gắng cập nhật Entity_A thì cho tôi ngoại lệ này, làm cách nào tôi có thể cập nhật Entity_A?
FAndrew

@FAndrew lưu Entity_B trước?
rogerdpack

3
và nếu tôi có ví dụ 100 Thực thể_B, tôi tìm kiếm tất cả Thực thể_B đã chỉnh sửa và nếu nó đã được chỉnh sửa tôi có cập nhật nó không? Sẽ không đẹp hơn nếu tôi chỉ cập nhật Entity_A?
FAndrew

6

Điều này có thể đơn giản như:

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

nhưng trong khi vẫn tồn tại, giá trị của "Some_Column" là null, ngay cả khi "Some_Column" có thể không phải là bất kỳ khóa chính hoặc khóa ngoại nào.


2

Kiểm tra các giá trị chưa được lưu cho khóa chính / ID đối tượng trong tệp hbm của bạn. Nếu bạn đã tự động tạo ID bằng khuôn khổ ngủ đông và bạn đang đặt ID ở đâu đó, nó sẽ xuất hiện lỗi này. Theo mặc định, giá trị chưa được lưu là 0, vì vậy nếu bạn đặt ID thành 0, bạn sẽ thấy lỗi này.


0

Tôi cũng gặp phải lỗi tương tự nhưng cuối cùng đã giải quyết được nó, thực sự là tôi đã không đặt Đối tượng thực thể đã được lưu vào thực thể khác và do đó giá trị Đối tượng mà nó nhận được cho khóa foreeign là rỗng.


0

Tôi đã giải quyết bằng cách xóa thuộc tính @Basic (tùy chọn = sai) hoặc chỉ cập nhật boolean @Basic (tùy chọn = đúng)


-10

Đặt biến đó ở dạng tạm thời. Vấn đề của bạn sẽ được giải quyết ..

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

3
Bạn đang nói về việc giải quyết lỗi và không giải quyết được vấn đề.
Karthik R
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.