Почему я получаю сообщение об ошибке «Нулевое значение было присвоено свойству установки примитивного типа» при использовании HibernateCriteriaBuilder в Grails

100

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

Ответы:

168

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

Питер
источник
6
Все услуги Codehaus прекращены.
Прияншу Чаухан
46

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

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

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

  private Integer num;

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

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

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

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

MattC
источник
13

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

Нхат Динь
источник
8

Я постараюсь объяснить вам это на примере. Предположим, у вас есть реляционная таблица (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;
    }

}

Предположим, в таблице уже были записи. Теперь, если кто-то попросит вас добавить еще один столбец «ВОЗРАСТ» (int)

ALTER TABLE STUDENT ADD AGE int NULL

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

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

или

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

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

codechefvaibhavkashyap
источник
6

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

private Integer num;

public Integer getNum()...

public void setNum(Integer num)...
арн-арн
источник
4

Не используйте примитивы в своих классах Entity , используйте вместо них соответствующие обертки. Это решит эту проблему.

Вне своих классов Entity вы можете использовать проверку! = Null для остальной части потока кода.

Израильм
источник
3

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

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

am0wa
источник
3

Есть два пути

  • Убедитесь, что столбец db не разрешен null
  • Классы User Wrapper для переменной примитивного типа, например, private int var;могут быть инициализированы какprivate Integer var;
4302836
источник
2

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

public void setClient_os_id(Integer clientOsId) {
client_os_id = clientOsId;
}
Камиэль Ахмадпур
источник
2

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

public void setPhoneNumber(Long phoneNumber) {
    if (phoneNumber != null)
        this.phoneNumber = phoneNumber;
    else
        this.extension = 0l;
}
Сандип Шанкар Харикришнан
источник
2
@Column(name ="LEAD_ID")
private int leadId; 

Изменить на

@Column(name ="LEAD_ID")
private Integer leadId; 
Ракеш Ядав
источник
1

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

Аравинтан К
источник