Почему при использовании HibernateCriteriaBuilder в Grails появляется сообщение об ошибке «Было присвоено нулевое значение свойству установщика примитивного типа» - PullRequest
79 голосов
/ 01 июля 2010

Я получаю следующую ошибку при использовании атрибута примитива в моем доменном объекте 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)

Ответы [ 11 ]

132 голосов
/ 01 июля 2010

В соответствии с этим SO потоком , решение состоит в том, чтобы использовать непримитивные типы-обертки; например, Integer вместо int.

40 голосов
/ 17 декабря 2012

Нулевое значение не может быть присвоено примитивному типу, например, int, long, boolean и т. Д. Если столбец базы данных, соответствующий полю в вашем объекте, может быть нулевым, то ваше поле должно быть классом-оболочкой, например Integer , Long, Boolean и т. Д.

Опасность состоит в том, что ваш код будет работать нормально, если в БД нет нулей, но завершится ошибкой после вставки нулей.

И вы всегда можете вернуть примитивный тип из геттера. Пример:

  private Integer num;

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

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

Но в большинстве случаев вы захотите вернуть класс-оболочку.

Так что либо установите в столбце БД недопустимые значения, либо используйте класс-оболочку.

12 голосов
/ 22 января 2013

Примитивный тип не может быть нулевым. Таким образом, решение состоит в том, чтобы заменить примитивный тип классом-оболочкой в ​​вашем файле tableName.java. Такие как:

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

ссылка http://en.wikipedia.org/wiki/Primitive_wrapper_class, чтобы найти класс-оболочку типа примитива.

6 голосов
/ 11 июня 2016

Я постараюсь, чтобы вы поняли с помощью примера.Предположим, у вас была реляционная таблица (STUDENT) с двумя столбцами и ID (int) и NAME (String).Теперь, как ORM, вы бы сделали класс сущности примерно следующим образом: -

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

}

Предположим, что в таблице уже есть записи.Теперь, если кто-то попросит вас добавить еще один столбец «AGE» (int)

ALTER TABLE STUDENT ADD AGE int NULL

Вам нужно будет установить значения по умолчанию как NULLдобавить еще один столбец в предварительно заполненную таблицу.Это заставит вас добавить еще одно поле в классе.Теперь возникает вопрос, будете ли вы использовать примитивный тип данных или тип данных не примитивной оболочки для объявления поля.

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

или

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

вам нужно будет объявить поле как тип данных не примитивной оболочки, потому что контейнер попытается сопоставить таблицу с сущностью.Следовательно, он не сможет отобразить значения NULL (по умолчанию), если вы не объявите поле как обертку и в конечном итоге выбросите «Нулевое значение было присвоено свойству установщика примитивного типа» Exception.

5 голосов
/ 05 декабря 2013

используйте Integer в качестве типа и предоставьте соответственно метод установки / получения ..

private Integer num;

public Integer getNum()...

public void setNum(Integer num)...
2 голосов
/ 17 июля 2016

Измените тип параметра с простого на Object и установите нулевую проверку в установщике. Смотрите пример ниже

public void setPhoneNumber(Long phoneNumber) {
    if (phoneNumber != null)
        this.phoneNumber = phoneNumber;
    else
        this.extension = 0l;
}
2 голосов
/ 31 марта 2016

Либо полностью избегайте null в БД через NOT NULL и в сущности Hibernate через @Column(nullable = false) соответственно, либо используйте оболочку Long вместо ваших long примитивов.

Примитив не является объектом, поэтому вы не можете присвоить ему null.

2 голосов
/ 20 июля 2014

@ Дин Нхат, ваш метод установки выглядит неправильно, потому что вы снова поместили примитивный тип, и он должен быть:

public void setClient_os_id(Integer clientOsId) {
client_os_id = clientOsId;
}
1 голос
/ 31 августа 2018

Существует два способа:

  • . Убедитесь, что столбец db недопустим. null
  • .1008 *
1 голос
/ 16 апреля 2015

Убедитесь, что в вашей базе данных myAttribute поле содержит ноль вместо нуля.

...