web-dev-qa-db-fra.com

Pourquoi est-ce que je reçois un message d'erreur "Une valeur nulle a été affectée à une propriété de type primitif", lors de l'utilisation de HibernateCriteriaBuilder dans Grails

L'erreur suivante s'affiche lors de l'utilisation d'un attribut primitif dans mon objet de domaine 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)
81
Peter

Selon ce SO SO , la solution consiste à utiliser les types de wrapper non primitifs; Par exemple, Integer au lieu de int.

136
Peter

Une valeur null ne peut pas être affectée à un type primitif, tel que int, long, boolean, etc. Si la colonne de la base de données qui correspond au champ de votre objet peut être null, votre champ doit être une classe wrapper, telle que Integer, Long, Booléen, etc.

Le danger est que votre code fonctionne correctement s'il n'y a pas de null dans la base de données, mais échouera une fois que les null sont insérés.

Et vous pouvez toujours renvoyer le type primitif depuis le getter. Ex:

  private Integer num;

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

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

Mais dans la plupart des cas, vous voudrez renvoyer la classe wrapper.

Vous devez donc définir votre colonne de base de données pour ne pas autoriser les valeurs NULL ou utiliser une classe wrapper.

40
MattC

Un type primitif ne peut pas être nul. La solution consiste donc à remplacer le type primitif par la classe wrapper primitive dans votre fichier nomTable.Java. Tel que:

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

référence http://en.wikipedia.org/wiki/Primitive_wrapper_class pour trouver la classe wrapper d'un type primivite.

12
Nhat Dinh

Je vais essayer de vous faire comprendre à l'aide d'un exemple. Supposons que vous disposiez d'une table relationnelle (STUDENT) avec deux colonnes et ID (int) et NAME (String). Maintenant, en tant qu'ORM, vous auriez créé une classe d'entités à peu près comme suit: -

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

}

Supposons que la table ait déjà des entrées. Maintenant, si quelqu'un vous demande d'ajouter une autre colonne de "AGE" (int)

ALTER TABLE ÉTUDIANT AJOUTER ÂGE int NULL

Vous devez définir les valeurs par défaut sur NULL pour ajouter une autre colonne dans un tableau prérempli. Cela vous fait ajouter un autre champ dans la classe. Maintenant, la question se pose de savoir si vous utiliserez un type de données primitif ou un type de données wrapper non primitif pour déclarer le champ.

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

ou

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

vous devrez déclarer le champ en tant que type de données wrapper non primitif car le conteneur tentera de mapper la table avec l'entité. Il ne pourrait donc pas mapper les valeurs NULL (par défaut) si vous ne déclarez pas champ comme wrapper et finirait par jeter "Une valeur nulle a été affectée à une propriété de type primitif" Exception.

6

utilisez Integer comme type et fournissez le setter/getter en conséquence.

private Integer num;

public Integer getNum()...

public void setNum(Integer num)...
5
arn-arn

@Dinh Nhat, votre méthode de définition n'a pas l'air bonne parce que vous y mettez un type primitif qui devrait être:

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

Evitez complètement null dans la base de données via NOT NULL Et dans l'entité Hibernate via @Column(nullable = false) en conséquence, ou utilisez Long wrapper à la place de vous long primitives .

Une primitive n’est pas un objet, vous ne pouvez donc pas lui affecter null.

2
am0wa

Modifiez le type de paramètre de primitive à Object et cochez la case NULL. Voir exemple ci-dessous

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

Assurez-vous que votre base de données myAttribute contient null au lieu de zéro.

1
Aravinthan K

Il y a deux voies

  • Assurez-vous que la colonne db n’est pas autorisée null
  • Les classes utilisateur wrapper pour la variable de type primitive comme private int var; peut être initialisé comme private Integer var;
1
4302836

N'utilisez pas de primitives dans votre classes d'entité, utilisez plutôt leurs wrappers respectifs. Cela résoudra ce problème.

Hors de vos classes d'entité, vous pouvez utiliser la validation! = Null pour le reste de votre flux de code.

0
Israelm