fbpx

@Entity en JPA

Las entidades en JPA no son más que un POJO que contienen la anotación @Entity que representan datos que se pueden conservar en la base de datos. Una entidad representa una tabla almacenada en una base de datos. Cada instancia de una entidad representa una fila en la tabla.

Video explicativo

Anotación @Entity en clases

Para especificar que nuestra clase será usada como una entidad de una fila de nuestra tabla en nuestra base de datos, deberemos de indicarla con la anotación @Entity. También debemos asegurarnos de que la entidad tenga un constructor sin argumentos y una clave principal:

@Entity
public class Empleado {
    
    // atributos, getters y setters
    
}

El nombre de la entidad por defecto es el nombre de la clase. Podemos cambiar su nombre usando el elemento de nombre:

@Entity(name = "empleados")
public class Empleado {
    
    // atributos, getters y setters
    
}

Debido a que varias implementaciones de JPA intentarán subclasificar nuestra entidad para proporcionar su funcionalidad, las clases de entidad no deben declararse finales.

La anotación @Id

Cada entidad JPA debe tener una clave principal que la identifique de forma única. La anotación @Id define la clave principal. Podemos generar los identificadores de diferentes maneras, que se especifican mediante la anotación @GeneratedValue.

Podemos elegir entre cuatro estrategias de generación de id con el elemento de estrategia. El valor puede ser AUTO, TABLE, SEQUENCE, or IDENTITY:

@Entity
public class Empleado {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    private String nombre;
    
    // ...
}

Si especificamos GenerationType.AUTO, el proveedor de JPA utilizará cualquier estrategia que desee para generar los identificadores.

Si anotamos los campos de la entidad, el proveedor de JPA utilizará estos campos para obtener y establecer el estado de la entidad. Además del acceso de campo, también podemos hacer acceso de propiedad o acceso mixto, lo que nos permite usar tanto el acceso de campo como el de propiedad en la misma entidad.

La anotación @Table

En la mayoría de los casos, el nombre de la tabla en la base de datos y el nombre de la entidad no serán iguales.

En estos casos, podemos especificar el nombre de la tabla usando la anotación @Table:

@Entity
@Table(name="EMPLEADOS")
public class Empleado {
    
    // ...
    
}

También podemos mencionar el esquema usando el elemento schema:

@Entity
@Table(name="EMPLEADOS", schema="EMPRESA")
public class Empleado {
    
    // ...
    
}

El nombre del esquema ayuda a distinguir un conjunto de tablas de otro.

Si no usamos la anotación @Table, el nombre de la tabla será el nombre de la entidad.

La anotación @Column

Al igual que la anotación @Table, podemos usar la anotación @Column para mencionar los detalles de una columna en la tabla.

La anotación @Column tiene muchos elementos, como nombre, longitud, anulable y único:

@Entity
@Table(name="EMPLEADOS")
public class Empleado {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @Column(name="EMPLEADO_NOMBRE", length=50, nullable=false, unique=false)
    private String name;
    
    // ...
}

El elemento de nombre especifica el nombre de la columna en la tabla. El elemento de longitud especifica su longitud. El elemento anulable especifica si la columna es anulable o no, y el elemento único especifica si la columna es única.

Si no especificamos esta anotación, el nombre de la columna en la tabla será el nombre del campo.

La anotación @Transient

A veces, es posible que queramos hacer que un campo no sea persistente. Podemos usar la anotación @Transient para hacerlo. Especifica que el campo no será persistente.

Por ejemplo, podemos calcular la edad de un estudiante a partir de la fecha de nacimiento.

Así que anotemos la antigüedad del campo con la anotación @Transient:

@Entity
@Table(name="EMPLEADOS")
public class Empleado {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "EMPLEADO_NOMBRE", length = 50, nullable = false)
private String name;

@Transient
private Integer edad;

// ...

}

Como resultado, el campo edad no se conservará en la tabla.

La anotación @Temporal

En algunos casos, es posible que tengamos que guardar valores temporales en nuestra tabla.

Para esto, tenemos la anotación @Temporal:

@Entity
@Table(name="EMPLEADOS")
public class Empleado {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "EMPLEADO_NOMBRE", length = 50, nullable = false)
private String name;

@Transient
private Integer edad;

@Temporal(TemporalType.DATE)
private Date cumpleanio;

// ...

}

Sin embargo, con JPA 2.2, también tenemos soporte para java.time.LocalDate, java.time.LocalTime, java.time.LocalDateTime, java.time.OffsetTime y java.time.OffsetDateTime. Ejemplo:

@Entity
@Table(name="EMPLEADOS")
public class Empleado {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "EMPLEADO_NOMBRE", length = 50, nullable = false)
private String name;

@Transient
private Integer edad;

@Column
private LocalDateTime dateTime;

// ...

}

La anotación @Enumerated

A veces, es posible que deseemos conservar un tipo de enumeración de Java.

Podemos usar la anotación @Enumerated para especificar si la enumeración debe persistir por nombre o por ordinal (predeterminado):

public enum Genero { 
MASCULINO,
FEMENINO,
OTRO
}
@Entity
@Table(name="EMPLEADOS")
public class Empleado {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "EMPLEADO_NOMBRE", length = 50, nullable = false)
private String name;

@Transient
private Integer edad;

@Column
private LocalDateTime dateTime;

@Enumerated(EnumType.STRING)
private Genero genero;

// ...

}

En realidad, no tenemos que especificar la anotación @Enumerated en absoluto si vamos a persistir el Genero por el ordinal de la enumeración.

Sin embargo, para conservar Género por nombre de enumeración, hemos configurado la anotación con EnumType.STRING.