Una de las principales características cuando trabajamos con base de datos es que todas las tablas tienen Columnas, y dichas columnas esta mapeadas contra los atributos de las entidades, para lo cual es necesario que JPA identifique que columna mapea contra cada atributo de la clase y es aquí donde entra @Column.
@Column
La anotación @Column nos permitirá definir aspectos muy importantes sobre las columnas de la base de datos de la base de datos como lo es el nombre, la longitud, constrains, etc. En caso de no definir esta anotación en los atributos, JPA determinara el nombre de la columna de forma automática mediante el nombre del atributo, por lo que siempre es recomendable establecer esta anotación en todos los atributos de la clase y evitarnos problemas.
Las propiedades que podemos definirle a @Column son las siguientes:
- name: Permite establecer el nombre de la columna de la tabla con la que el atributo debe de mapear. A pesar de que ningún atributo de @Column es obligatorio, este atributo siempre recomiendo establecerlo.
- length: Permite definir la longitud de la columna en caracteres, solo aplica para Strings, en los demás tipos de datos será omitida. Solo se utiliza cuando JPA creará las tablas.
- insertable: Le indica a JPA si esa columna debe ser tomada en cuenta en los inserts, en caso de ser true, el valor será insertado, en caso contrario el valor será omitido y será colocado el valor default de la columna o null.
- updatable: Parecido al caso anterior, solo que en este caso la columna se toma en cuenta para operaciones de Update.
- nullable: Crea una restricción en la tabla (Not Null) para impedir que se inserten valores nulos. Solo se utiliza cuando JPA creará las tablas.
- precisión:
- scale: Utilizada únicamente para columnas que deben tener decimales, como valore recibe el número de decimales. Solo se utiliza cuando JPA creará las tablas.
- table: Esta propiedad es muy avanzada y la analizaremos más adelante. Se utiliza cuando existe herencia en las entidades y las columnas pueden estar distribuidas en más de una tabla.
- unique: Creara una restricción en la tabla para que sea el valor de esa columna sea única. Solo se utiliza cuando JPA creará las tablas.
Para comprender como funciona la anotación @Column retomaremos la entidad Employee que hemos venido analizando en todo el tutorial: Recordemos como la habíamos dejo en las secciones anteriores:
@Entity @Table( name = "EMPLOYEES" , schema = "jpatutorial", indexes = {@Index(name = "name_index", columnList = "name",unique = true)} ) public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "EmployeeTable") private Long id; @Column(name = "NAME", nullable = false, length = 150) private String name; }
Ahora bien, para utilizar el mayor número de características agregaremos un par de atributos más, agregaremos el salario y la fecha de ingreso del empleado. Veamos cómo quedaría:
@Entity @Table( name = "EMPLOYEES" , schema = "jpatutorial", indexes = {@Index(name = "name_index", columnList = "name",unique = true)} ) public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "EmployeeTable") @Column(name = "ID") private Long id; @Column(name = "NAME", nullable = false, length = 150) private String name; @Column(name = "SALARY", nullable = false, scale = 2) private double salary; @Column(name = "REGIST_DATE", updatable = false, nullable = false) @Temporal(TemporalType.DATE) private Calendar registDate; }
Veamos que el atributo id, solo requiere definir la propiedad name, pues por default, ya es única, no nula, no actualizable. Por lo que con definir el nombre será necesario.
En el caso del nombre, definimos la propiedad name, le indicamos que no puede ser nulo y le estamos definiendo una longitud de 150 caracteres.
En el caso del salario también ponemos el nombre, le indicamos que el suledo puede tener 2 decimales y que no debe de ser nulo.
Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST, https://codmind.com/courses/jpa
Finalmente, en la fecha de registro también establecemos el nombre, pero en este caso veamos que el nombre de la columna es diferente que el de la propiedad y es cuando es especialmente necesario definir la propiedad name, le indicamos que no debe de ser nulo y finalmente, la fecha de ingreso no debe de ser actualizable. Por el momento no tomemos en cuenta la anotación @Temporal, más adelante la estudiaremos
Definición de la tabla:
En las imágenes vemos como quedarían las tablas generadas por JPA, veamos que ID es llave primaria y es auto incremental, todas las columnas son not null y el nombre tiene una longitud de 150 caracteres.
NOTA: Este artículo es solo una sección del Tutorial de JPA, para ver el contenido completo de este tutorial regresa al Índice en el botón de abajo.
Hola muy buen post! me sirvio mucho.
Tengo una duda, es necesario definir todas las columnas de la tabla en mi entidad? suponiendo que la tabla ya existe y tiene 9 columnas pero solo necesito 4 en mi aplicación.
Muchas gracias!
Si, es posible, solo toma en cuenta que al momento de insertar el valor del resto de columnas será NULL, así que deberás tener cuidado que las columnas sean no sean Not Null
Buenas, gracias por compartir sus conocimientos.
Un apunte, no se si estoy en lo cierto pero por si acaso le comento en en este sección que se habla de @Column y en concreto de su propiedad name comenta:
“name: Permite establecer el nombre de la tabla de la base de datos ”
Supongo que debería decir nombre de la COLUMNA, en vez de la TABLA.
Saludos cordiales
Hola Javier, si, lo que comentas es correcto, acabo de corregirlo, muchas gracias por la observación.
buenas como hago para que JPA Obvie un campo en el select. logre con
@Column(name = “nro_cbu”, updatable = false,insertable = false)
private String nroCbu;
que no se actualizen ni quiera insertarse pero al momento de hacer una consulta me salta el error que el campo no existe lo cual es cierto. ya que ese campo nroCbu pertenece a otra tabla
Hola Sebastian, lo que entiendo es que ese campo sea omitido en su totalidad por JPA, es decir, que no lo inserte, actualice o le lea, en tal caso, solo tienes que anotarlo con @Transient, aquí explico como funciona: https://www.oscarblancarteblog.com/2016/11/30/atributos-volatiles-transient/
saludos.
muchisimas gracias, era eso. gracias por tu predisposición de ayudar!! soy nuevo en esta arquitectura y hay cosas que se me escapan
Excelente Sebastian, suerte con tu proyecto.
Hola!
Tengo una duda enorme, tengo una api que va a insertar a la base de datos ya creada. Pero mi tabla tiene campos con valores default.
Cómo puedo indicar que si no le asigno valor a esa propiedad, al momento de insertar tome el valor por default de la tabla?
Gracias de antemano!
Hola Valeria, tendrías que indicar que el campo es `Nullable`, para eso puedes usar la propiedad `nullable` en `true` de `@Column`, esto hará que permite permita guardar la columna en Null y la base de datos por debajo asignará el valor por default.
La otra opción es que al momento de declarar la variable le asignes el valor, para que cuando instancias la Entidad ya tenga el valor por default, por ejemplo: `private String Status = “Active”`.
saludos.
¿Como podia poner que en caso de no añadir campos se inicialice una variable a un valor determinado?
ejemplo
name = Luis
is_admin = false
Muchas gracias!
Hola Luis, tienes dos formas, la primera y mas facil, es definir el valor justo cuando defines el atributo, por ejemplo
private String name = "Luis";
, la otra es usar la propiedad columnDefinition de@Column
, por ejemplo@Column(columnDefinition = "varchar(255) default 'Luis'")
.saludos.
Hola Oscar, tengo 2 bases de datos donde tengo la misma tabla solo que en una de ellas tengo una columna que en la otra no, hay alguna forma de poner una columna opcional? o tendría que mapear 2 tablas diferentes solo por ese campo?
Hola Carlos, no eso no es posible, por que una Entidad mapea contra una tabla espesifica, por que si la tabla varía en su definición, entonces no estamos hablando de la misma tabla, lo que si se permite es que ignores el campo extra, lo que pasará es que JPA no lo trabajará, pero si lo agregas, es importante que exista en las dos tablas.
Hola Oscar, tengo una tabla donde mis columnas comienzan en mayuscula por ejemplo:
Id_TablaEjemplo
Pero cuando creo un servicio este se muestra de la siguiente manera:
[
{
“idTablaEjemplo”: 1
}
]
Hay alguna forma de que se muestre tal cual como esta en el nombre de la columna: ‘Id_TablaEjemplo’ ?
Saludos.
Si, hay una propiedad que pones en el archivo persistence.xml, no recuerdo la propiedad, pero eso le indica que respete los nombres tal cual están definidos en las anotaciones, en Hibernate la propiedad es
PhysicalNamingStrategyStandardImpl
, googleala a ver que encuentrasMuy amable y gracias por la pista. Saludos
No hay de que 😉