Perché ottengo un messaggio di errore "Il valore Null è stato assegnato a una proprietà del tipo primitivo setter di" quando utilizzo HibernateCriteriaBuilder in Grails


100

Ottengo il seguente errore quando utilizzo un attributo primitivo nel mio oggetto di dominio grails:

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)

non rovinare i tuoi dati immessi e non dovrai usare wrapper non primitivi. Non sono riuscito a inserire alcuni valori e sono riuscito a correggere questo errore aggiungendolo al database.
Goot

Risposte:


168

Secondo questo thread SO , la soluzione consiste nell'usare i tipi wrapper non primitivi; ad esempio, Integerinvece di int.


6
Tutti i servizi Codehaus sono stati terminati.
Priyanshu Chauhan

46

Un valore null non può essere assegnato a un tipo primitivo, come int, long, boolean, ecc. Se la colonna del database che corrisponde al campo nell'oggetto può essere null, il campo dovrebbe essere una classe wrapper, come Integer, Long, Booleano, ecc.

Il pericolo è che il codice funzioni correttamente se non ci sono null nel DB, ma fallirà una volta inseriti i null.

E puoi sempre restituire il tipo primitivo dal getter. Ex:

  private Integer num;

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

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

Ma nella maggior parte dei casi vorrai restituire la classe wrapper.

Quindi imposta la colonna DB in modo che non consenta valori nulli o utilizza una classe wrapper.


13

Un tipo primitivo non può essere nullo. Quindi la soluzione è sostituire il tipo primitivo con la classe wrapper primitiva nel file tableName.java. Ad esempio:

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

fare riferimento a http://en.wikipedia.org/wiki/Primitive_wrapper_class per trovare la classe wrapper di un tipo primivite.


8

Proverò a farti capire con l'aiuto di un esempio. Supponiamo di avere una tabella relazionale (STUDENT) con due colonne e ID (int) e NAME (String). Ora come ORM avresti creato una classe di entità un po 'come la seguente: -

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

}

Supponiamo che la tabella contenga già voci. Ora se qualcuno ti chiede di aggiungere un'altra colonna di "AGE" (int)

ALTER TABLE STUDENT ADD AGE int NULL

Dovrai impostare i valori predefiniti come NULL per aggiungere un'altra colonna in una tabella precompilata. Questo ti fa aggiungere un altro campo nella classe. Ora sorge la domanda se utilizzerai un tipo di dati primitivo o un tipo di dati wrapper non primitivo per dichiarare il campo.

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

o

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

dovrai dichiarare il campo come tipo di dati wrapper non primitivo perché il contenitore proverà a mappare la tabella con l'entità. Quindi non sarebbe in grado di mappare i valori NULL (impostazione predefinita) se non si dichiara il campo come wrapper e alla fine si genera "Il valore Null è stato assegnato a una proprietà del tipo primitivo setter" Eccezione.


6

usa Integer come tipo e fornisci setter / getter di conseguenza.

private Integer num;

public Integer getNum()...

public void setNum(Integer num)...

4

Non usare primitive nelle tue classi Entity , usa invece i loro rispettivi wrapper. Questo risolverà questo problema.

Fuori dalle tue classi di entità puoi usare la convalida! = Null per il resto del flusso di codice.


3

O evita completamente nullnel DB tramite NOT NULLe nell'entità Hibernate tramite di @Column(nullable = false)conseguenza o usa il Longwrapper al posto delle tue longprimitive.

Una primitiva non è un oggetto, quindi non puoi assegnarle null.


3

Ci sono due modi

  • Assicurati che la colonna db non sia consentita null
  • Le classi di wrapper utente per la variabile di tipo primitivo come private int var;possono essere inizializzate comeprivate Integer var;

2

@Dinh Nhat, il tuo metodo setter sembra sbagliato perché hai inserito di nuovo un tipo primitivo e dovrebbe essere:

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

2

Modificare il tipo di parametro da primitivo a Object e inserire un controllo nullo nel setter. Vedi esempio sotto

public void setPhoneNumber(Long phoneNumber) {
    if (phoneNumber != null)
        this.phoneNumber = phoneNumber;
    else
        this.extension = 0l;
}

2
@Column(name ="LEAD_ID")
private int leadId; 

Cambia in

@Column(name ="LEAD_ID")
private Integer leadId; 

1

Assicurati che il campo myAttribute del tuo database contenga null invece di zero.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.