web-dev-qa-db-ja.com

GrailsでHibernateCriteriaBuilderを使用すると、「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)
81
Peter

この SOスレッド によると、解決策は非プリミティブラッパータイプを使用することです。例:Integerの代わりにint

136
Peter

Null値をint、long、booleanなどのプリミティブ型に割り当てることはできません。オブジェクトのフィールドに対応するデータベース列がnullになる可能性がある場合、フィールドはInteger、Long、ブール値など.

危険なのは、DBにヌルがない場合はコードが正常に実行されるが、ヌルが挿入されると失敗することです。

そして、ゲッターからプリミティブ型をいつでも返すことができます。例:

  private Integer num;

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

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

ただし、ほとんどの場合、ラッパークラスを返します。

したがって、NULLを許可しないようにDB列を設定するか、ラッパークラスを使用します。

40
MattC

プリミティブ型をnullにすることはできません。したがって、解決策は、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 プリミティブ型のラッパークラスを検索します。

12
Nhat Dinh

例の助けを借りてあなたに理解してもらおうと思います。 2つの列とID(int)およびNAME(String)を持つリレーショナルテーブル(STUDENT)があるとします。 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値がプリミティブ型セッターのプロパティに割り当てられました」例外をスローします。

型として整数を使用し、それに応じてセッター/ゲッターを提供します。

private Integer num;

public Integer getNum()...

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

@Dinh Nhat、プリミティブ型を再度配置するため、セッターメソッドが間違っているように見えます。

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

DBで_NOT NULL_を介してnullを完全に回避し、それに応じて@Column(nullable = false)を介してHibernateエンティティを回避するか、Longプリミティブの代わりにlongラッパーを使用します。

プリミティブはオブジェクトではないため、nullを割り当てることはできません。

2
am0wa

パラメータタイプをプリミティブからObjectに変更し、セッターにnullチェックを入れます。以下の例を参照してください

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

データベースmyAttributeフィールドにゼロではなくnullが含まれていることを確認してください。

1
Aravinthan K

二つの方法があります

  • Db列が許可されていないことを確認してくださいnull
  • private int var;などのプリミティブ型変数のユーザーラッパークラスは、private Integer var;として初期化できます。
1
4302836

Entityクラスでプリミティブを使用せず、代わりにそれぞれのラッパーを使用します。これでこの問題は解決します。

Entityクラスのうち、残りのコードフローに!= null検証を使用できます。

0
Israelm