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)
この SOスレッド によると、解決策は非プリミティブラッパータイプを使用することです。例:Integer
の代わりにint
。
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列を設定するか、ラッパークラスを使用します。
プリミティブ型を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 プリミティブ型のラッパークラスを検索します。
例の助けを借りてあなたに理解してもらおうと思います。 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)...
@Dinh Nhat、プリミティブ型を再度配置するため、セッターメソッドが間違っているように見えます。
public void setClient_os_id(Integer clientOsId) {
client_os_id = clientOsId;
}
DBで_NOT NULL
_を介してnull
を完全に回避し、それに応じて@Column(nullable = false)
を介してHibernateエンティティを回避するか、Long
プリミティブの代わりにlong
ラッパーを使用します。
プリミティブはオブジェクトではないため、null
を割り当てることはできません。
パラメータタイプをプリミティブからObjectに変更し、セッターにnullチェックを入れます。以下の例を参照してください
public void setPhoneNumber(Long phoneNumber) {
if (phoneNumber != null)
this.phoneNumber = phoneNumber;
else
this.extension = 0l;
}
データベースmyAttributeフィールドにゼロではなくnullが含まれていることを確認してください。
二つの方法があります
null
private int var;
などのプリミティブ型変数のユーザーラッパークラスは、private Integer var;
として初期化できます。Entityクラスでプリミティブを使用せず、代わりにそれぞれのラッパーを使用します。これでこの問題は解決します。
Entityクラスのうち、残りのコードフローに!= null検証を使用できます。