Mengapa saya mendapatkan pesan galat “Nilai kosong ditugaskan ke properti penyetel tipe primitif” saat menggunakan HibernateCriteriaBuilder di Grails

100

Saya mendapatkan kesalahan berikut saat menggunakan atribut primitif di objek domain grails saya:

Null value was assigned to a property of primitive type setter of MyDomain.myAttribute
 org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of MyDomain.myAttribute
at grails.orm.HibernateCriteriaBuilder.invokeMethod(HibernateCriteriaBuilder.java:1077)
Peter
sumber
jangan mengacaukan input data Anda dan Anda tidak perlu menggunakan pembungkus non-primitif. Saya melewatkan beberapa nilai dan saya berhasil memperbaiki kesalahan ini dengan menambahkannya ke database.
Goot

Jawaban:

168

Menurut thread SO ini , solusinya adalah dengan menggunakan jenis pembungkus non-primitif; misalnya, Integeralih-alih int.

Peter
sumber
6
Semua layanan Codehaus telah dihentikan.
Priyanshu Chauhan
46

Nilai null tidak dapat ditetapkan ke tipe primitif, seperti int, long, boolean, dll. Jika kolom database yang sesuai dengan kolom di objek Anda bisa null, maka kolom Anda harus kelas pembungkus, seperti Integer, Long, Boolean, dll.

Bahayanya adalah bahwa kode Anda akan berjalan dengan baik jika tidak ada null di DB, tetapi akan gagal setelah null dimasukkan.

Dan Anda selalu bisa mengembalikan tipe primitif dari getter. Ex:

  private Integer num;

  public void setNum(Integer i) {
    this.num = i;
  }

  public int getNum() {
    return this.num;
  }

Tetapi dalam banyak kasus, Anda ingin mengembalikan kelas pembungkus.

Jadi, setel kolom DB Anda agar tidak mengizinkan null, atau gunakan kelas pembungkus.

MattC
sumber
13

Tipe primitif tidak boleh nol. Jadi solusinya adalah mengganti tipe primitif dengan kelas pembungkus primitif di file tableName.java Anda. Seperti:

@Column(nullable=true, name="client_os_id")
private Integer client_os_id;

public int getClient_os_id() {
    return client_os_id;
}

public void setClient_os_id(int clientOsId) {
    client_os_id = clientOsId;
}

rujuk http://en.wikipedia.org/wiki/Primitive_wrapper_class untuk menemukan kelas pembungkus dari tipe primivit.

Nhat Dinh
sumber
8

Saya akan mencoba membuat Anda mengerti dengan bantuan contoh. Misalkan Anda memiliki tabel relasional (STUDENT) dengan dua kolom dan ID (int) dan NAME (String). Sekarang sebagai ORM Anda akan membuat kelas entitas seperti berikut: -

package com.kashyap.default;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author vaibhav.kashyap
 *
 */
@Entity
@Table(name = "STUDENT")
public class Student implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -1354919370115428781L;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "NAME")
    private String name;

    public Student(){

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Mari kita asumsikan tabel sudah memiliki entri. Sekarang jika seseorang meminta Anda menambahkan kolom "AGE" (int)

ALTER TABLE SISWA TAMBAHKAN USIA int NULL

Anda harus menetapkan nilai default sebagai NULL untuk menambahkan kolom lain di tabel yang telah diisi sebelumnya. Ini membuat Anda menambahkan bidang lain di kelas. Sekarang muncul pertanyaan apakah Anda akan menggunakan tipe data primitif atau tipe data pembungkus non primitif untuk mendeklarasikan bidang.

@Column(name = "AGE")
private int age;

atau

@Column(name = "AGE")
private INTEGER age;

Anda harus mendeklarasikan bidang sebagai tipe data pembungkus non primitif karena penampung akan mencoba memetakan tabel dengan entitas. Oleh karena itu, ia tidak akan dapat memetakan nilai NULL (default) jika Anda tidak mendeklarasikan bidang sebagai pembungkus & pada akhirnya akan menampilkan "Nilai Null ditugaskan ke properti penyetel tipe primitif" Pengecualian.

codechefvaibhavkashyap
sumber
6

gunakan Integer sebagai tipe dan berikan penyetel / pengambil yang sesuai ..

private Integer num;

public Integer getNum()...

public void setNum(Integer num)...
arn-arn
sumber
4

Jangan gunakan primitif di kelas Entitas Anda , sebagai gantinya gunakan pembungkusnya masing-masing. Itu akan memperbaiki masalah ini.

Di luar kelas Entitas, Anda dapat menggunakan validasi! = Null untuk sisa alur kode Anda.

Israelm
sumber
3

Baik sepenuhnya menghindari nulldi DB melalui NOT NULLdan di entitas Hibernate melalui @Column(nullable = false)sesuai atau menggunakan Longpembungkus sebagai pengganti Anda longprimitif.

Primitif bukanlah sebuah Objek, oleh karena itu u tidak dapat menugaskannya null.

am0wa
sumber
3

Ada dua cara

  • Pastikan kolom db tidak diperbolehkan null
  • Kelas Pembungkus Pengguna untuk variabel tipe primitif seperti private int var; dapat diinisialisasi sebagaiprivate Integer var;
4302836
sumber
2

@Dinh Nhat, metode penyetel Anda terlihat salah karena Anda meletakkan tipe primitif di sana lagi dan seharusnya:

public void setClient_os_id(Integer clientOsId) {
client_os_id = clientOsId;
}
Kamiel Ahmadpour
sumber
2

Ubah tipe parameter dari primitif ke Object dan beri tanda centang pada penyetel. Lihat contoh di bawah ini

public void setPhoneNumber(Long phoneNumber) {
    if (phoneNumber != null)
        this.phoneNumber = phoneNumber;
    else
        this.extension = 0l;
}
Sandeep Shankar Harikrishnan
sumber
2
@Column(name ="LEAD_ID")
private int leadId; 

Mengubah

@Column(name ="LEAD_ID")
private Integer leadId; 
Rakesh Yadav
sumber
1

Pastikan bidang myAttribute database Anda berisi null, bukan nol.

Aravinthan K
sumber