Почему при использовании HibernateCriteriaBuilder в Grails мне присваивается значение "Null" для свойства сообщения об ошибках примитивного типа?

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

Ответ 1

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

Ответ 2

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

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

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

  private Integer num;

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

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

Но в большинстве случаев вам нужно вернуть класс оболочки.

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

Ответ 3

Примитивный тип не может быть нулевым. Таким образом, решение заменяет примитивный тип примитивным классом-оболочкой в ​​файле 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, чтобы найти класс-оболочку примитивного типа.

Ответ 4

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

private Integer num;

public Integer getNum()...

public void setNum(Integer num)...

Ответ 5

@Dinh Nhat, ваш метод setter выглядит неправильно, потому что вы снова вводите примитивный тип, и он должен быть:

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

Ответ 6

Я попытаюсь понять вас с помощью примера. Предположим, что у вас была реляционная таблица (STUDENT) с двумя столбцами и идентификатором (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 (по умолчанию), если вы не объявите поле в качестве обертки и в конечном итоге выбросите "Значение Null было присвоено свойству примитивного типа" Исключение ".

Ответ 7

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

Ответ 8

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

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

Ответ 9

Измените тип параметра с примитива на объект и поместите нулевую проверку в установщик. Пример ниже

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