Saltar al contenido

¿Qué es un identificador natural en Hibernate?

Este grupo de expertos pasados varios días de trabajo y de recopilar de información, obtuvimos los datos necesarios, deseamos que resulte útil para ti en tu plan.

Solución:

En Hibernate, natural keys se utilizan a menudo para búsquedas. Tendrá una identificación sustituta generada automáticamente en la mayoría de los casos. Pero esta identificación es bastante inútil para las búsquedas, ya que siempre consultará por campos como nombre, número de seguro social o cualquier otra cosa del mundo real.

Al usar las funciones de almacenamiento en caché de Hibernate, esta diferencia es muy importante: si el caché está indexado por su principal key (identificación sustituta), no habrá ninguna ganancia de rendimiento en las búsquedas. Es por eso que puede definir un conjunto de campos con los que consultará la base de datos: la identificación natural. Hibernate puede entonces indexar los datos por su natural key y mejorar el rendimiento de búsqueda.

Consulte esta excelente publicación de blog para obtener una explicación más detallada o esta página de RedHat para ver un archivo de mapeo de Hibernate de ejemplo.

En un sistema de base de datos relacional, por lo general, puede tener dos tipos de identificadores simples:

  • Natural keysque son asignados por sistemas externos y garantizados como únicos
  • Sustituto keysme gusta IDENTITY o SEQUENCE que son asignados por la base de datos.

La razón por la que las claves sustitutas son tan populares es que son más compactas (4 u 8 bytes), en comparación con una clave natural que es muy larga (por ejemplo, el VIN tiene 17 caracteres alfanuméricos, el ISBN del libro tiene 13 dígitos). Si la clave sustituta se convierte en la clave principal, puede asignarla utilizando el JPA @Id anotación.

Ahora, supongamos que tenemos lo siguiente Post entidad:

Publicar entidad con identificación natural

Desde el Post entidad que también tiene una clave natural, además de la sustituta, puede mapearla con la clave específica de Hibernate @NaturalId anotación:

@Entity(name = "Post")
@Table(name = "post")
public class Post 
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String title;
 
    @NaturalId
    @Column(nullable = false, unique = true)
    private String slug;
 
    //Getters and setters omitted for brevity
 
    @Override
    public boolean equals(Object o) 
        if (this == o) return true;
        if (o == null 
 
    @Override
    public int hashCode() 
        return Objects.hash(slug);
    

Ahora, considerando la entidad anterior, el usuario podría haber marcado un Post artículo y ahora quieren leerlo. Sin embargo, la URL marcada contiene el slug Identificador natural, no la clave principal.

Entonces, podemos obtenerlo así usando Hibernate:

Post post = entityManager.unwrap(Session.class)
.bySimpleNaturalId(Post.class)
.load(slug); 

E Hibernate ejecutará las siguientes dos consultas:

SELECT p.id AS id1_0_
FROM post p
WHERE p.slug = 'high-performance-java-persistence'
 
SELECT p.id AS id1_0_0_,
       p.slug AS slug2_0_0_,
       p.title AS title3_0_0_
FROM post p
WHERE p.id = 1

La primera consulta es necesaria para resolver el identificador de entidad asociado con el identificador natural proporcionado.

La segunda consulta es opcional si la entidad ya está cargada en el caché de primer o segundo nivel.

La razón de tener la primera consulta es porque Hibernate ya tiene una lógica bien establecida para cargar y asociar entidades por su identificador en el contexto de persistencia.

Ahora, si desea omitir la consulta del identificador de entidad, puede anotar fácilmente la entidad usando el @NaturalIdCache anotación:

@Entity(name = "Post")
@Table(name = "post")
@org.hibernate.annotations.Cache(
    usage = CacheConcurrencyStrategy.READ_WRITE
)
@NaturalIdCache
public class Post 
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String title;
 
    @NaturalId
    @Column(nullable = false, unique = true)
    private String slug;
 
    //Getters and setters omitted for brevity
 
    @Override
    public boolean equals(Object o)  getClass() != o.getClass()) 
            return false;
        Post post = (Post) o;
        return Objects.equals(slug, post.slug);
    
 
    @Override
    public int hashCode() 
        return Objects.hash(slug);
    

De esta manera, puede obtener el Post entidad sin siquiera acceder a la base de datos. ¿Guay, verdad?

Un identificador natural es algo que se usa en el mundo real como identificador. Un ejemplo es un número de seguro social o un número de pasaporte.

Por lo general, es una mala idea usar identificadores naturales como keys en una capa de persistencia porque a) se pueden cambiar fuera de su control, yb) pueden terminar no siendo únicos debido a un error en otro lugar, y luego su modelo de datos no puede manejarlo, por lo que su aplicación explota.

Sección de Reseñas y Valoraciones

Si te gusta el proyecto, eres capaz de dejar una división acerca de qué te ha parecido esta reseña.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *