Vou tentar fazer você entender com a ajuda de um exemplo. Suponha que você tenha uma tabela relacional (STUDENT) com duas colunas e ID (int) e NAME (String). Agora, como ORM, você teria feito uma classe de entidade mais ou menos como a seguinte: -
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;
}
}
Vamos supor que a tabela já tenha entradas. Agora, se alguém pedir para você adicionar outra coluna de "AGE" (int)
ALTER TABLE STUDENT ADD AGE int NULL
Você terá que definir os valores padrão como NULL para adicionar outra coluna em uma tabela pré-preenchida. Isso faz com que você adicione outro campo na classe. Agora surge a pergunta se você usará um tipo de dados primitivo ou um tipo de dados wrapper não primitivo para declarar o campo.
@Column(name = "AGE")
private int age;
ou
@Column(name = "AGE")
private INTEGER age;
você terá que declarar o campo como tipo de dados de wrapper não primitivo porque o contêiner tentará mapear a tabela com a entidade. Conseqüentemente, ele não seria capaz de mapear valores NULL (padrão) se você não declarasse o campo como wrapper e eventualmente emitisse "Valor nulo atribuído a uma propriedade do setter de tipo primitivo" Exceção.