<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Base de datos &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<atom:link href="https://www.oscarblancarteblog.com/tag/base-de-datos/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.oscarblancarteblog.com</link>
	<description>Software Architect &#38; FullStack developer</description>
	<lastBuildDate>Thu, 13 May 2021 01:55:01 +0000</lastBuildDate>
	<language>es-MX</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.15</generator>

<image>
	<url>https://www.oscarblancarteblog.com/wp-content/uploads/2019/03/cropped-ob-32x32.png</url>
	<title>Base de datos &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<link>https://www.oscarblancarteblog.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">89905023</site>	<item>
		<title>Datalake una nueva forma de análisis de datos</title>
		<link>https://www.oscarblancarteblog.com/2021/05/13/datalake-una-nueva-forma-de-analisis-de-datos/</link>
					<comments>https://www.oscarblancarteblog.com/2021/05/13/datalake-una-nueva-forma-de-analisis-de-datos/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 13 May 2021 01:46:56 +0000</pubDate>
				<category><![CDATA[EAI]]></category>
		<category><![CDATA[Base de datos]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=3326</guid>

					<description><![CDATA[<p>Los lagos de datos son repositorios donde las aplicaciones dejan su información en bruto para poder ser analizados y explotados</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2021/05/13/datalake-una-nueva-forma-de-analisis-de-datos/">Datalake una nueva forma de análisis de datos</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="577" src="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/banner-1024x577.jpg" alt="" class="wp-image-3336" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/banner-1024x577.jpg 1024w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/banner-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/banner-768x433.jpg 768w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/banner.jpg 1196w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>No es un secreto que las aplicaciones de hoy en día generan una gran cantidad de datos y sumado a eso, cada vez tenemos más aplicaciones independientes que van produciendo datos de forma aislada, por tal motivo, llegara un momento en que los datos están distribuidos en varias base de datos, por lo que recuperar información relevante y consistente, nos obliga a crear complejos procesos de extracción y cargado de datos (ETL) para integrarlos en una única fuente confiable para finalmente sea analizada y explotable, sin embargo, como analizaremos en este artículo, este enfoque tiene grandes problemas, entre los que destaca los complicados procesos de extracción y los múltiples procesos ETL que deben de correr una y otra vez para obtener diferente información para diferentes análisis o reportes.</p>



<span id="more-3326"></span>



<h1>Antecedentes</h1>



<p>Cuando las herramientas como Business Intelligence (BI) comenzaron a ponerse de moda, predominaban las aplicaciones monolíticas, donde cada aplicación podía contener una gran cantidad de información sobre una parte del negocio:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="954" height="371" src="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/1-datalake-db-por-aplicacion.png" alt="Datalake una nueva forma de análisis de datos" class="wp-image-3328" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/1-datalake-db-por-aplicacion.png 954w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/1-datalake-db-por-aplicacion-300x117.png 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/1-datalake-db-por-aplicacion-768x299.png 768w" sizes="(max-width: 954px) 100vw, 954px" /></figure>



<p>Debido a que los sistemas eran grandes silos datos, era muy simple crear procesos ETL para extraer información de estos sistemas y crear los famosos Data warehouses o almacenes de datos, desde los cuales las herramientas de BI generaban sus reportes:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="916" src="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/2-datalake-db-por-aplicacion-etl-1024x916.png" alt="Datalake una nueva forma de análisis de datos" class="wp-image-3329" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/2-datalake-db-por-aplicacion-etl-1024x916.png 1024w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/2-datalake-db-por-aplicacion-etl-300x268.png 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/2-datalake-db-por-aplicacion-etl-768x687.png 768w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/2-datalake-db-por-aplicacion-etl.png 1053w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>A pesar de que esto es suficiente para muchas empresas, el problema llega cuando se requieren reportes más complejos, donde la información se recolecta de múltiples sistemas para generar un solo reporte, creando una sobre carga de las bases de datos transaccionales, pues múltiples procesos extraen información para diferentes almacenes de datos:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="749" src="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/3-datalake-db-por-aplicacion-etl-datawarehouse-1024x749.png" alt="Datalake una nueva forma de análisis de datos" class="wp-image-3330" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/3-datalake-db-por-aplicacion-etl-datawarehouse-1024x749.png 1024w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/3-datalake-db-por-aplicacion-etl-datawarehouse-300x219.png 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/3-datalake-db-por-aplicacion-etl-datawarehouse-768x562.png 768w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/3-datalake-db-por-aplicacion-etl-datawarehouse.png 1266w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Lo que estamos viendo en la imagen anterior es un caso muy común que he visto en muchas empresas, donde tiene varios procesos ETL que extraen información del mismo sistema, pero como son varios procesos, los tiene que programar a diferentes horas de la noche o del día para que no corran en simultaneo.</p>



<p>Si prestamos atención en la imagen anterior, podrás observar que el ERP es utilizado por 3 procesos ETL para crear diferentes almacenes de datos, y muy probablemente los 3 procesos ETL consulten prácticamente la misma información, pero la procesen de forma diferente, entonces, como la procesan diferente según su objetivo, hace necesario crear cuantos procesos ETL sea necesario para satisfacer todas las necesidades del negocio, lo cual, queda claro que no es para nada eficiente.</p>



<h1>¿La solución es un Stagin Area?</h1>



<p>Dada la problemática anterior, quizás los más experimentados digan, bueno, pues creamos un Stagin Area en donde volquemos todos los datos y sobre esa base de datos corremos los procesos ETL. Veamos como quedaría:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="968" height="1024" src="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/4-datalake-db-por-aplicacion-stagingarea-968x1024.png" alt="Datalake una nueva forma de análisis de datos" class="wp-image-3331" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/4-datalake-db-por-aplicacion-stagingarea-968x1024.png 968w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/4-datalake-db-por-aplicacion-stagingarea-284x300.png 284w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/4-datalake-db-por-aplicacion-stagingarea-768x812.png 768w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/4-datalake-db-por-aplicacion-stagingarea.png 1266w" sizes="(max-width: 968px) 100vw, 968px" /></figure>



<p>En esta nueva arquitectura tenemos proceso de extracción que solo extraen los datos una vez de los sistemas transaccionales y los dejan en los Stagin Area, los cuales al nos ser transaccionales, permite que múltiples procesos ETL se conecten a ellos para extraer la información y crear sus propios almacenes de datos. Este enfoque tiene varias ventas:</p>



<ul><li>Extraemos la información una sola vez de los sistemas transaccionales.</li><li>Permite que los procesos ETL se conecten a los Stagin Area a la hora que sea sin comprometer la operatividad del negocio.</li><li>Tenemos un mejor control sobre los procesos que extraen información de los sistemas transaccionales.</li></ul>



<p>Entonces estarás pensando, listo, problema resuelto, cerremos todo y vamos a casa a descansar, sin embargo, hay una pequeña que no hemos sumado a la ecuación…. Los microservicios y las arquitecturas distribuidas, que es aquí donde todo comienza a complicarse, pues en lugar de tener grandes fuentes de datos, tenemos múltiples fuentes, donde cada una cuenta una parte de la historia y para poder tener toda la historia, necesitamos recopilar información de múltiples puntos.</p>



<h1>Datalake</h1>



<p>El problema ( o la ventaja, depende de como lo veas) es que en arquitecturas de microservicios no tenemos enormes sistemas desde los cuales obtener los datos, si no que es necesario recopilar datos de varias fuentes solo para poder crear un reporte:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="796" src="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/5-datalake-microservicios-1024x796.png" alt="Datalake una nueva forma de análisis de datos" class="wp-image-3332" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/5-datalake-microservicios-1024x796.png 1024w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/5-datalake-microservicios-300x233.png 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/5-datalake-microservicios-768x597.png 768w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/5-datalake-microservicios.png 1333w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Bajo esta arquitectura se hace impráctico tener múltiples Stagin Area, ya que se tendrían que mantener demasiadas bases de datos, por eso, se propone los Datalake o Lagos de datos, los cuales cambian considerablemente la forma en que los datos se extraen y se procesan.</p>



<p>Un lago de datos es básicamente un vertedero donde son las mismas aplicaciones quienes dejan los datos, en lugar de ser extraídos por un proceso, por otra parte, un Datalake es único, esto quiere decir todas las aplicaciones dejan los datos en el mismo lugar. Creando un lago de datos donde los demás procesos se pueden servir.</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="655" src="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/6-datalake-sincronizacion-1024x655.png" alt="Datalake una nueva forma de análisis de datos" class="wp-image-3333" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/6-datalake-sincronizacion-1024x655.png 1024w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/6-datalake-sincronizacion-300x192.png 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/6-datalake-sincronizacion-768x491.png 768w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/6-datalake-sincronizacion.png 1213w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Este enfoque puede resultar controversial, pero a medida que avancemos en este artículo, iremos resolviendo algunas dudas que puedan surgir, así que por lo pronto, solo ve analizando esto.</p>



<p>Lo primero que debemos entender respecto al Datalake es que son las mismas aplicaciones las que deciden que información mandar al lago y el formato de la misma, por que cada aplicación es dueña de su parte del lago. De la misma forma, esta tiene la libertada de agregar, quitara o modificar la estructura de la misma, ya que cada aplicación determina que y como la información se envía al Datalake. Aunque claro, siempre será mejor no hacer cambios demasiados bruscos.</p>



<p>Otro aspecto del lago es que la información es incremental y no está procesada, esto quiere decir que los sistemas van depositando solamente la nueva información (aun que podrían borrar y cargar toda la data), pero al mismo tiempo, la información no está procesada al momento de dejarla en el lago, si no que se deja en bruto.</p>



<p>En este nuevo enfoque son los interesados los encargados en buscar que información les sirve y cual no, al mismo tiempo que se puede obtener información de múltiples aplicaciones de forma simultánea. Ha esto yo le llamo los ríos del lago, ya que cada interesado deshoja del lago la información que le sirve para su propósito para dejarla en un data warehouse ya procesada:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="948" height="1024" src="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/7-datalake-rios-948x1024.png" alt="Datalake una nueva forma de análisis de datos" class="wp-image-3334" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/7-datalake-rios-948x1024.png 948w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/7-datalake-rios-278x300.png 278w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/7-datalake-rios-768x829.png 768w, https://www.oscarblancarteblog.com/wp-content/uploads/2021/05/7-datalake-rios.png 1214w" sizes="(max-width: 948px) 100vw, 948px" /></figure>



<p>Este enfoque es especialmente útil en entornos de Big Data y análisis de datos, ya que todos los sistemas van depositando la data en bruto en un mismo lugar, lo que facilita para que los científicos de datos puedan explotar la información, además, es posible contrastarla con la data de los demás sistemas.</p>



<h1>Reservas respecto a la seguridad</h1>



<p>Uno de los aspectos más cuestionados sobre este enfoque es la seguridad de los datos, ya que una persona con acceso total al lago tiene visión completa de lo que pasa en todos los sistemas, lo cual no es una observación menor, por lo que hay que tener especia cuidado sobre los accesos que damos a este. No hay una formula clara o única para resolver esto, salvo que limitar bien el acceso al lago y tener acuerdo de confidencialidad bien estipulados.</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2021/05/13/datalake-una-nueva-forma-de-analisis-de-datos/">Datalake una nueva forma de análisis de datos</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2021/05/13/datalake-una-nueva-forma-de-analisis-de-datos/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3326</post-id>	</item>
		<item>
		<title>Relación muchos a uno con @ManyToOne</title>
		<link>https://www.oscarblancarteblog.com/2018/12/06/relacion-muchos-a-uno-con-manytoone/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/06/relacion-muchos-a-uno-con-manytoone/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 06 Dec 2018 18:30:22 +0000</pubDate>
				<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2449</guid>

					<description><![CDATA[<p>Una de las grandes ventajas que tiene trabajar con JPA, es que te permite hacer relaciones con otras entidades, de esta forma, es posible agregar otras Entidades como atributos de clase y JPA se encargará de realizar el SELECT adicional para cargar esas Entidades.   Para comprender esto, analicemos el ejemplo de las facturas, estas [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/06/relacion-muchos-a-uno-con-manytoone/">Relación muchos a uno con @ManyToOne</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="aligncenter wp-image-2458 size-large" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/jpa-manytoone-1024x575.jpg" alt="Relación muchos a uno con @ManyToOne" width="648" height="364" />Una de las grandes ventajas que tiene trabajar con JPA, es que te permite hacer relaciones con otras entidades, de esta forma, es posible agregar otras Entidades como atributos de clase y JPA se encargará de realizar el SELECT adicional para cargar esas Entidades.<span id="more-2449"></span></p>
<p> </p>
<p>Para comprender esto, analicemos el ejemplo de las facturas, estas siempre son emitidas a un cliente, por lo que el objeto Factura siempre deberá tener una propiedad que represente al cliente. Normalmente, esta propiedad seria el ID, sin embargo, JPA nos permite tener una referencia a la Entidad cliente. Veamos cómo quedaría la Entidad <span class="lang:default decode:true crayon-inline ">Invoice</span>  (factura)</p>
<pre class="lang:java decode:true " title="Invoice.java">package com.obb.jpa.jpaturorial.entity;

import java.util.Calendar;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name="INVOICES")
public class Invoice {
    
    @Id
    @Column(name="ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    
    @Column(name = "STATUS", length = 20, nullable = false)
    @Enumerated(EnumType.STRING)
    private Status status;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "REGIST_DATE", nullable = false)
    private Calendar registDate;
    
    @ManyToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Customer customer;

    /** GET and SET */
}</pre>
<p> </p>
<p>Como podemos apreciar, hemos utiliza la anotación <span class="lang:default decode:true crayon-inline ">@ManyToOne</span> , la cual nos permite mapear una entidad con otra. Como única regla, es necesario la clase que sea una entidad, es decir, que también esté anotada con <span class="lang:default decode:true crayon-inline ">@Entity</span> .</p>
<p> </p>
<p>Por otro lado, tenemos la entidad <span class="lang:default decode:true crayon-inline ">Customer</span> , la cual se ve de la siguiente manera:</p>
<pre class="lang:java decode:true" title="Customer.java">package com.obb.jpa.jpaturorial.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "CUSTOMERS")
public class Customer {
    
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    
    @Column(name = "NAME", nullable = false, length = 100)
    private String name;

    /** GET and SET */
}</pre>
<p> </p>
<p>Estas dos entidades nos crearán las siguientes tablas:</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-2450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/diagrama-db.jpg" alt="JPA ManyToOne tables" width="649" height="271" /></p>
<p> </p>
<p>La anotación @ManyToOne cuenta con los siguientes atributos:</p>
<ul>
<li><strong>Optional</strong>: indica si la relación es opcional, es decir, si el objeto puede ser null. Esta propiedad se utiliza optimizar las consultas. Si JPA sabe que una relación es opcional, entonces puede realizar un <span class="lang:default decode:true crayon-inline ">RIGHT JOIN</span>  o realizar la consulta por separado, mientras que, si no es opcional, puede realizar un <span class="lang:default decode:true crayon-inline ">INNER JOIN</span>  para realizar una solo consulta.</li>
<li><strong>Cascade</strong>: Esta propiedad le indica que operaciones en cascada puede realizar con la Entidad relacionada, los valores posibles son <span class="lang:default decode:true crayon-inline ">ALL</span> , <span class="lang:default decode:true crayon-inline ">PERSIST</span> , <span class="lang:default decode:true crayon-inline ">MERGE</span> , <span class="lang:default decode:true crayon-inline ">REMOVE</span> , <span class="lang:default decode:true crayon-inline ">REFRESH</span> , <span class="lang:default decode:true crayon-inline">DETACH</span> y están definidos en la enumeración <span class="lang:default decode:true crayon-inline ">javax.persistence.CascadeType</span> .</li>
<li><strong>Fetch</strong>: Esta propiedad se utiliza para determinar cómo debe ser cargada la entidad, los valores están definidos en la enumeración <span class="lang:default decode:true crayon-inline ">javax.persistence.FetchType</span>  y los valores posibles son:
<ul>
<li><strong>EAGER</strong> (ansioso): Indica que la relación debe de ser cargada al momento de cargar la entidad.</li>
<li><strong>LAZY</strong> (perezoso): Indica que la relación solo se cargará cuando la propiedad sea leída por primera vez.</li>
</ul>
</li>
<li><strong>targetEntity</strong>: Esta propiedad recibe una clase (<span class="lang:default decode:true crayon-inline ">Class</span> ) la cual corresponde a la clase de la relación. No suele ser utilizada, pues JPA puede inferir la clase por el tipo de la propiedad.</li>
</ul>
<p>En nuestro caso, hemos definido la propiedad <strong>optional</strong> en false, pues toda factura debe de tener forzosamente un Cliente (customer). La propiedad <strong>cascade</strong> la definimos en <span class="lang:default decode:true crayon-inline ">ALL</span>  para facilitarnos la explicación de este ejemplo, pero más adelante en este tutorial analizaremos las cascadas en profundidad. La propiedad <strong>fetch</strong> la definimos en <span class="lang:default decode:true crayon-inline ">EAGER</span> , aun que para este tipo de relación es su valor por default y no sería necesario definirlo.</p>
<p> </p>
<h2>Ejemplo práctico</h2>
<p>Crearemos un pequeño ejemplo que nos permita comprobar cómo trabajar con esta relación, para ello, crearemos una nueva factura con un cliente:</p>
<pre class="lang:java decode:true">public static void main(String[] args) {
    EntityManager manager = EntityManagerUtil.getEntityManager();
        
    Customer customer = new Customer();
    customer.setName("ACME Corp");
      
    Invoice invoice = new Invoice();
    invoice.setCustomer(customer);
    invoice.setRegistDate(Calendar.getInstance());
    invoice.setStatus(Status.ACTIVE);
        
    manager.getTransaction().begin();
    manager.persist(invoice);
    manager.getTransaction().commit();
}</pre>
<p> </p>
<p>Como resultado, podemos observar como han sido insertados la Factura y el Cliente:</p>
<figure id="attachment_2452" aria-describedby="caption-attachment-2452" style="width: 342px" class="wp-caption aligncenter"><img loading="lazy" class="wp-image-2452 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoices-select.jpg" alt="JPA Invoices ManyToOne relationship" width="342" height="179" /><figcaption id="caption-attachment-2452" class="wp-caption-text">Tabla de las facturas</figcaption></figure>
<figure id="attachment_2451" aria-describedby="caption-attachment-2451" style="width: 296px" class="wp-caption aligncenter"><img loading="lazy" class="wp-image-2451 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/customers-select.jpg" alt="JPA Customers ManyToOne relationship" width="296" height="177" /><figcaption id="caption-attachment-2451" class="wp-caption-text">Tabla de los clientes</figcaption></figure>
<p>Por otra parte, si consultamos la Entidad Invoice, JPA se encargará de cargar al Empleado, vamos el siguiente ejemplo:</p>
<pre class="lang:java decode:true">public static void main(String[] args) {
    EntityManager manager = EntityManagerUtil.getEntityManager();
    Invoice invoice = manager.find(Invoice.class, 1L);
        
    System.out.println("Invoice ID &gt; " + invoice.getId());
    System.out.println("Customer ID &gt; " + invoice.getCustomer().getId());
    System.out.println("Customer Name &gt; " + invoice.getCustomer().getName());
}</pre>
<p> </p>
<p>Como podemos apreciar en la siguiente imagen, no fue necesario ir a consultar el Cliente por separado, si no que JPA se encarga de recuperarlo justo en el momento en que lo necesitamos.</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-2453" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/manytoone-select.jpg" alt="JPA ManyToOne select" width="332" height="81" /></p>
<p> </p>
<p>Finalmente, podemos ver en las siguiente imágenes como es que nos auto genero la tabla de las facturas, en ella podemos apreciar el campo <span class="lang:default decode:true crayon-inline ">CUSTOMER_ID</span> , el cual es en realidad una llave foránea a la tabla de clientes:</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-2454" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/table-sstructure.png" alt="JPA ManyToOne table" width="784" height="239" /></p>
<p> </p>
<p>JPA también nos ayuda a crear los Foreign Keys con la tabla de Clientes:</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-2455" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/table-keys.png" alt="JPA ManyToOne foreign keys" width="383" height="59" /></p>
<p> </p>
<p><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST, </strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)"><strong>https://codmind.com/courses/jpa</strong></a></p>
<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noopener noreferrer"><img loading="lazy" width="800" height="450" class="wp-image-3085 lazy-loaded" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" sizes="(max-width: 800px) 100vw, 800px" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-768x432.jpg 768w" alt="" data-lazy-type="image" data-src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" data-srcset="" /></a>
<figcaption>Los invito a mi <a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label="Curso de Mastering JPA (opens in a new tab)">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.</figcaption>
</figure>
<p> </p>
<h2>Conclusiones</h2>
<p>Hemos podido observar como JPA se encarga de todo lo relacionado a persistir o recuperar el cliente de la base de datos, sin embargo, hay algo que no hemos cubierto, y es la forma en que podemos personalizar la columna, es decir, como podemos indicarle el nombre, si admite nulos o no, etc. Todas esta propiedades las podremos definir en la anotación <span class="lang:default decode:true crayon-inline ">@JoinColumn</span>  que analizaremos en la siguiente parte del tutorial</p>
<p> </p>


<center><a class="btn btn-default read-more " style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2017/03/09/jpa-resource-local-transaction/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more " style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2018/12/13/personalizar-las-relaciones-con-joincolumn/	">Siguiente </a></center>



<div style="height:87px" aria-hidden="true" class="wp-block-spacer"></div>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/06/relacion-muchos-a-uno-con-manytoone/">Relación muchos a uno con @ManyToOne</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2018/12/06/relacion-muchos-a-uno-con-manytoone/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2449</post-id>	</item>
		<item>
		<title>Entity Manager &#038; Persistence Context</title>
		<link>https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/</link>
					<comments>https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 21 Feb 2017 12:33:40 +0000</pubDate>
				<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=1392</guid>

					<description><![CDATA[<p>Hasta el momento solo hemos trabajado con el Entity Manager para realizar las operaciones básicas, pero existen detalles más finos que es necesario entender para convertirnos en expertos de JPA. Cuando trabajamos con JPA es común interactuar con el Entity Manager, ¿pero que tanto sabemos acerca de los Persistence Context en realidad? &#160; Primero que [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/">Entity Manager &#038; Persistence Context</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>				<img loading="lazy" class="size-full wp-image-603 alignleft" src="https://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg" alt="Tutorial de JPA persistence.xml" width="150" height="83" />Hasta el momento solo hemos trabajado con el Entity Manager para realizar las operaciones básicas, pero existen detalles más finos que es necesario entender para convertirnos en expertos de JPA. Cuando trabajamos con JPA es común interactuar con el Entity Manager, ¿pero que tanto sabemos acerca de los Persistence Context en realidad?</p>
<p>&nbsp;</p>
<p>Primero que nada, tenemos que saber que el Persistence Context se crea mediante un Persistence Unit y el Entity Manager se crea a partir de un Persistence Context, veamos la siguiente imagen para entender mejor:</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-1394" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/02/Persistence-Context.png" alt="persistence context" width="661" height="308" /></p>
<p>&nbsp;</p>
<p>Veamos que todo parte del archivo <a href="https://www.oscarblancarteblog.com/2016/10/26/entitymanager-archivo-persistence-xml/">persistence.xml</a> del cual ya hablamos anteriormente, en este archivo se definen los Persistence Unit, y mediante estos es creado el Persistence Context, el Persistence Context tiene la finalidad de delimitar el alcance de las transacciones, pero también está delimitado a administrar las Entidades definidas por el Persistence Unit con el que fue creado.  Adicionalmente, el Entity Manager hace referencia a un Persistence Context el cual será utilizado para administrar las entidades y las transacciones.<span id="more-1392"></span></p>
<p>&nbsp;</p>
<p>Una de las ventajas de tener varios Persistence Unit, es que nos permite definir diferentes configuraciones para cada uno, de esta manera podemos delimitar las entidades de cada módulo e incluso una configuración de base de datos diferentes para cada uno.</p>
<p>&nbsp;</p>
<h2>Container-Managed Entity Manager</h2>
<p>&nbsp;</p>
<p>Básicamente existen dos formas de trabajar con JPA, la más simple es cuando lo utilizamos en aplicaciones SE o de escritorio y la segunda forma que es la que estudiaremos en esta sección, es cuando lo utilizamos en ambientes de Java EE con EJB.</p>
<p>La principal característica de utilizar Entity Manager administrado por el contenedor, es que es el mismo Container el que se encarga de abrir y cerrar las transacciones, por lo que el programador solo se preocupa por implementar la lógica de negocio despreocupándose en la totalidad de las transacciones.</p>
<p>En ambientes Java EE se suele utilizar la anotación <span class="lang:java decode:true crayon-inline ">@PersistenceContext</span>  para crear el EntityManager, como veremos en el siguiente EJB.</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true" title="EmployeeDAO.java">package com.obb.jpa.jpaturorial.entitymanager;

import javax.ejb.*;
import javax.persistence.*;

/**
 * @author Oscar Blancarte
 */
@EJB
@Stateless
public class EmployeeDAO implements IEmployeeDAO{

    @PersistenceContext(unitName = "JPA_PU")
    private EntityManager manager;
}</pre>
<p>&nbsp;</p>
<p>Cuando utilizamos la anotación <span class="lang:java decode:true crayon-inline ">@PersistenceContext</span>  el contenedor inyecta de forma automática una referencia válida del EntityManager creado a partir de la Persistence Unit <strong>JPA_PU</strong>, de esta forma, el programador podrá utilizar el EntityManager en cualquier método que defina, y las transacciones será administradas de forma automática.</p>
<p>&nbsp;</p>
<p>Ahora bien, existen dos variantes de los Container-Managed, Transaction-Scope y Extended, los cuales son utilizados en circunstancias diferentes. Para utilizar una variante o la otra, es necesario definirlo en la anotación <span class="lang:java decode:true crayon-inline ">@PersistenceContext</span> <strong> </strong>mediante la propiedad <strong>type</strong>. Los valores posibles son <span class="lang:java decode:true crayon-inline">TRANSACTION</span>  y <span class="lang:java decode:true crayon-inline ">EXTENDED</span>  como veremos a continuación:</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true">@PersistenceContext(unitName = "JPA_PU", type = PersistenceContextType.TRANSACTION)
@PersistenceContext(unitName = "JPA_PU", type = PersistenceContextType.EXTENDED)</pre>
<p>&nbsp;</p>
<p>En caso de no definir la propiedad type, el valor por default será TRANSACTION, lo cual está bien, porque es por lejos la variante más utilizada.</p>
<p>&nbsp;</p>
<h3>Transaction-Scope</h3>
<p>&nbsp;</p>
<p>La variante Transaction-Scope es la variante utiliza por default, por lo que no es necesario definir la propiedad type para utilizarla. Esta variante tiene la particularidad de que el contexto de persistencia solo será válido durante le ejecución de la operación de negocio, una vez que la operación termine el contexto de persistencia se destruye y todas las entidades relacionadas con el Entity Manager será descartadas.</p>
<p>Este tipo de estrategias se utiliza para EJB sin estado como los <span class="lang:java decode:true crayon-inline">@Stateless</span>, pues cada invocación a una operación de negocio se espera que realice una acción, persista y retorne un resultado, y cada ejecución tendrá un contexto de persistencia diferente, garantizando de esta forma que el servicio siempre arroje el mismo resultado para la misma entrada.</p>
<p>Veamos un ejemplo de un servicio de creación de empleados:</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true">package com.obb.jpa.jpaturorial.entitymanager;
import com.obb.jpa.jpaturorial.entity.Employee; 
import javax.ejb.*; 
import javax.persistence.*; 
/** 
* @author Oscar Blancarte 
*/ 
@EJB 
@Stateless 
public class EmployeeDAO implements IEmployeeDAO{ 
@PersistenceContext(unitName = "JPA_PU", type = PersistenceContextType.TRANSACTION) 
private EntityManager manager; 

@TransactionAttribute(TransactionAttributeType.NEVER) 
public Employee getEmployeeById(Long empId){ 
//Se consulta el empleado mediante el ID 
return manager.find(Employee.class, empId); 
} 

@TransactionAttribute(TransactionAttributeType.SUPPORTS) 
public void updateEmployeeName(Long empId, String newName){ 
//El empleado es nuevamente consultado de la base de datos 
//debido a que cada invocación es un nuevo contexto de persistencia 
Employee emp = manager.find(Employee.class, empId); 
emp.setName(newName); 
//Al termina el método, el contenedor realiza un Commit automático. 
} 
}</pre>
<p>&nbsp;</p>
<p>Imaginemos el siguiente escenario, tenemos una aplicación que carga el empleado en pantalla utilizando el método <span class="lang:java decode:true crayon-inline ">getEmployeeById</span>, esta consulta al empleado mediante el ID y lo retorna, la aplicación utiliza el empleado consultado para mostrarlo en pantalla, luego, modificamos el nombre del empleado y guardamos los cambios mediante el método <span class="lang:java decode:true crayon-inline ">updateEmployeeName</span>.</p>
<p>Lo primero que hace la aplicación es consultar el empleado, hasta aquí todo bien, pero cuando actualizamos el nombre del empleado, vemos que realizamos un find mediante el ID del empleado, podríamos pensar que como ya lo hemos consultado anteriormente mediante el método <span class="lang:java decode:true crayon-inline">getEmployeeById</span> este solo lo retomará del cache sin realizar una nueva consulta a la base de datos, sin embargo, Transaction-Scope garantiza que cada ejecución crea un nuevo PersistenceContext en blanco, por lo que el empleado que anteriormente ya habíamos consultado será nuevamente consultado, debido que en la segunda llamada al método <span class="lang:java decode:true crayon-inline ">updateemployeeName</span> el Persistence Context está en blanco.</p>
<p>&nbsp;</p>
<p>No te preocupes por las anotaciones <span class="lang:java decode:true crayon-inline ">@TransactionAttribute</span>, más adelante las explicaremos por ahora pasémoslas por alto.</p>
<p>&nbsp;</p>
<h3>Extended</h3>
<p>&nbsp;</p>
<p>La segunda variante es Extended, que como su nombre nos lo indica, se trata de un Contexto de Persistencia Extendido, donde el contexto persistirá durante todo el tiempo de vida de la sesión, sin importar el número de operaciones o transacciones que se realicen.</p>
<p>A diferencia de Transaction-Scope, en esta variante todos los cambios realizados en el Persistence Context seguirán vigentes, por lo que cada ejecución que realicemos se favorecerá de las ejecuciones pasadas.</p>
<p>Este tipo de variante es utilizada cuando trabajamos con EJB con sesión como el <span class="lang:java decode:true crayon-inline">@Stateful</span>, veamos el mismo ejemplo anterior pero esta vez utilizando un EJB con sesión y la variante Extended.</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true " title="EmployeeExtendedDAO.java">package com.obb.jpa.jpaturorial.entitymanager;

import com.obb.jpa.jpaturorial.entity.Employee;
import javax.ejb.*;
import javax.persistence.*;

/**
 * @author Oscar Blancarte
 */
@EJB
@Stateful
public class EmployeeExtendedDAO implements IEmployeeDAO{
    
    @PersistenceContext(unitName = "JPA_PU", type = PersistenceContextType.EXTENDED)
    private EntityManager manager;
    
    @TransactionAttribute(TransactionAttributeType.NEVER)
    public Employee getEmployeeById(Long empId){
        //Se consulta el empleado mediante el ID
        return manager.find(Employee.class, empId);
    }
    
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public void updateEmployeeName(Long empId, String newName){
        //El empleado no es consultado, debido a que ya fue consultado previamente
        Employee emp = manager.find(Employee.class, empId);
        emp.setName(newName);
        //Al termina el método, el contenedor realiza un Commit automático.
        //Los camibios realizados seguiran estando disponibles
    }
}</pre>
<p>&nbsp;</p>
<p>En este caso las cosas son un poco diferentes. Primero que nada, se realiza la consulta del empleado mediante el método <span class="lang:java decode:true crayon-inline">getEmployeeById</span> y el empleado es retornado, cuando la ejecución del método termina, el Persistence Context continúa existiendo, por lo que cuando se realiza la actualización del nombre del empleado y se realiza la consulta del empleado, el Entity Manager ya no consulta al empleado, pues este ya fue consultado en el método anterior. Finalmente, el nombre es actualizado y al terminar el método se hace un commit de la transacción. Al finalizar el método el Contexto de persistencia continua activo hasta que la sesión finaliza.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Application-Managed Entity Manager</h2>
<p>&nbsp;</p>
<p>La segunda forma de trabajar con JPA es delegar al programador la responsabilidad de administrar las transacciones, este escenario se da con mucha más frecuencia en aplicaciones de escritorio, aunque existen escenarios donde es utilizado en entornos de Java EE.</p>
<p>Básicamente el programador tiene que crear el <strong>EntityManager</strong> a través del <strong>EntityManagerFactory</strong> y tiene que abrir y cerrar las transacciones cada vez que requiera.</p>
<p>Veamos cómo quedaría el escenario anteriormente planteado utilizando application-managed:</p>
<pre class="lang:java decode:true " title="EmployeeApplicationDAO.java">package com.obb.jpa.jpaturorial.entitymanager;

import com.obb.jpa.jpaturorial.entity.Employee;
import javax.ejb.*;
import javax.persistence.*;

/**
* @author Oscar Blancarte
*/
public class EmployeeApplicationDAO {

private EntityManager manager;

public EmployeeApplicationDAO() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA_PU");
manager = emf.createEntityManager();
}

public Employee getEmployeeById(Long empId) {
return manager.find(Employee.class, empId);
}

public void updateEmployeeName(Long empId, String newName) {
//Se abre la transacción manualmente
manager.getTransaction().begin();
Employee emp = manager.find(Employee.class, empId);
emp.setName(newName);
//Se cierra la transacción manulamente
manager.getTransaction().commit();
}
}</pre>
<p>Podemos apreciar que el constructor de la clase estamos creando manualmente el EntityManager en lugar de simplemente inyectarlo como el Container-Managed, la otra diferencia es en el método <span class="lang:java decode:true crayon-inline">updateEmployeeName</span>, ya que para poder persistir los cabios tenemos que abrir y cerrar la transacción con los métodos <strong>beign</strong> y <strong>commit</strong>.</p>
<p>&nbsp;</p>
<p><center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more " style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2016/12/20/introduccion-java-transaction-api-jta/">Siguiente </a></center>		</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/">Entity Manager &#038; Persistence Context</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1392</post-id>	</item>
		<item>
		<title>Introducción a Java Transaction API(JTA)</title>
		<link>https://www.oscarblancarteblog.com/2016/12/20/introduccion-java-transaction-api-jta/</link>
					<comments>https://www.oscarblancarteblog.com/2016/12/20/introduccion-java-transaction-api-jta/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 20 Dec 2016 09:00:56 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">http://www.oscarblancarteblog.com/?p=1316</guid>

					<description><![CDATA[<p>JTA o Java Transaction API es la encarga de administrar las transacciones del lado del servidor, abstrayendo casi en su totalidad al programador de abrir o cerrar las transacciones, de esta forma el programador únicamente se preocupa por la lógica de negocio aumentando drásticamente la productividad y los errores de Runtime. &#160; JTA es sin duda [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/12/20/introduccion-java-transaction-api-jta/">Introducción a Java Transaction API(JTA)</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>				<img loading="lazy" class="aligncenter size-full wp-image-1513" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/Guia_JPA_JTA.jpg" alt="Guia de JPA-JTA" width="744" height="417" />JTA o Java Transaction API es la encarga de <strong>administrar las transacciones</strong> del lado del servidor, abstrayendo casi en su totalidad al programador de abrir o cerrar las transacciones, de esta forma el programador únicamente se preocupa por la lógica de negocio aumentando drásticamente la productividad y los errores de Runtime.<span id="more-1316"></span></p>
<p>&nbsp;</p>
<p>JTA es sin duda unas de las API menos conocidas del Estándar de Java, pues si funcionamiento es abstraído casi en la totalidad por el Application Server, sin embargo, no puedo hacer todo el solo, y es necesario conocer cómo funciona y como indicarle a JTA como trabajar con las tracciones.</p>
<p>&nbsp;</p>
<p style="text-align: left;">Lo primero que debemos de saber es que JTA trabajo de la mano con los Enterprise Java Beans (EJB) a partir de la versión 3.0, mediante la unión de EJB + JPA + JTA, es posible crear componentes de negocio súper potentes y lo más interesantes, totalmente transaccionales. Esto quiere decir que todas las operaciones que realicemos en la invocación de un EJB queda envuelto es una transacción, sin importar cuantos EJB se ejecuten en la misma invocación o en varías. Te recomiendo repasar la sección anterior, <a href="https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/">EntityManager &amp; PersistenceContext</a> ya que te pondrá un poco en contexto sobre los Transaction-Scope.</p>
<p>&nbsp;</p>
<p>En la imagen anterior podemos apreciar cómo es que JTA administra las transacciones. El cliente invoca un servicio de negocio, antes de que el Application Server inicie la ejecución del EJB, este abre una transacción, seguido se ejecuta una serie de EJB los cuales pueden hacer múltiples operaciones sobre la base de datos. Cuando la ejecución de todo el flujo termina, el Servidor realiza un Commit y regresa los resultados al cliente.</p>
<p>&nbsp;</p>
<p>Cabe mencionar que lo explicaremos a continuación requiere de conocimientos previos de EJB, pues JTA se integra junto con JPA para crear una amalgama perfecta, donde es difícil entender dónde empieza uno y termina el otro. Además, esta no es una guía de EJB por lo que nos detendremos en explicar la teoría de EJB.</p>
<p>&nbsp;</p>
<h2>Java Transaction API (JTA)</h2>
<p>&nbsp;</p>
<p>Antes de empezar debemos de dejas claro que JTA solo funciona en ambientes de Java EE, pues es el Application Server quien administra las transacciones a través de JPA. En la siguiente sección hablaremos de cómo administrar las transacciones en Ambientes Java SE, por lo que por ahora lo dejaremos hasta aquí. Para configurar JPA para que utilice JPA, tendremos que regresar al archivo <a href="https://www.oscarblancarteblog.com/2016/10/26/entitymanager-archivo-persistence-xml/">persistence.xml</a> y ajustar la línea:</p>
<p style="text-align: justify;"><span class="lang:xhtml decode:true crayon-inline">&lt;persistence-unit name=&#8221;JPA_PU&#8221; transaction-type=&#8221;JTA&#8221;&gt;</span></p>
<p>Si bien JTA administrara las transacciones es importante decirle como, es por eso que aquí entra en juego la anotación <span class="lang:java decode:true crayon-inline">@TransactionAttribute</span> , la cual pude ser declarada en cada método de negocio o a nivel de clase. Existen 6 posibles valores, los cuales harán que el EJB Container funcione de forma diferente. Los valores son los siguientes:</p>
<p>&nbsp;</p>
<ul>
<li><strong>NOT_SUPPORTED:</strong> Indica que la operación no soporta transacciones, por lo que, si el método es ejecutado dentro de una transacción, esta se suspende durante la ejecución del método y se restaura una vez finalizado, por lo que todos los cambios realizados en estos métodos no serán persistentes.</li>
</ul>
<p><img loading="lazy" class="aligncenter wp-image-1515" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/JTA-NOT_SUPPORTED.png" alt="JPA-NOT_SUPPORTED" width="578" height="279" /></p>
<ul>
<li><strong>SUPPORTS:</strong> Indica que el método soporta transacciones, por lo que sí es ejecutado dentro de una transacción, este se unirá a la misma. Por otro lado, si es ejecutado fuera de una transacción este no creara ninguna transacción y todos los cambios realizados no se persistirán.</li>
</ul>
<p><img loading="lazy" class="aligncenter wp-image-1516" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/JTA-SUPPORT.png" alt="JTA-SUPPORT" width="576" height="432" /></p>
<ul>
<li><strong>REQUIRES_NEW:</strong> Indica que el método requiere forzosamente una nueva transacción para funcionar, por lo que se creará una nueva transacción independientemente de si es ejecutado dentro o fuera de una transacción existente.</li>
</ul>
<p><img loading="lazy" class="aligncenter wp-image-1517" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/JTA-REQUIRES_NEW.png" alt="JTA-REQUIRES_NEW" width="581" height="436" /></p>
<ul>
<li><strong>MANDATORY:</strong> Estas operaciones deberán ser ejecutadas forzosamente dentro de una transacción existente. En caso contrario se lanzará una Exception de tipo <span class="lang:java decode:true crayon-inline">javax.ejb.EJBTransactionRequiredException</span>.</li>
</ul>
<p><img loading="lazy" class="aligncenter wp-image-1518" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/JTA-MANDATORY.png" alt="JTA-MANDATORY" width="587" height="440" /></p>
<ul>
<li><strong>REQUIRED:</strong> Le indicamos que la operación requieres de una transacción, por lo que, si es ejecutado dentro de una transacción existente, este se unirá a la mima. Por otro lado, si no existe una transacción este creará una nueva.</li>
</ul>
<p><img loading="lazy" class="aligncenter wp-image-1519" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/JTA-REQUIRED.png" alt="JTA-REQUIRED" width="598" height="449" /></p>
<ul>
<li><strong>NEVER:</strong> Le indicamos que la operación por ningún motivo deberá ser ejecutado dentro de una transacción existente, ya que lanzará una Exception de tipo <span class="lang:java decode:true crayon-inline">javax.ejb.EJBException</span>. Si es ejecutado fuera de una transacción, tampoco creara una nueva.</li>
</ul>
<p><img loading="lazy" class="aligncenter wp-image-1520" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/JTA-NEVER.png" alt="JTA-NEVER" width="607" height="455" /></p>
<p>&nbsp;</p>
<p>Cuando <span class="lang:java decode:true crayon-inline">@TransactionAttribute</span> es declarada a nivel de clase, afectará a todas las operaciones definidas en el EJB, por otra parte, si es definida a nivel de método, solo afectara al método anotado. Cabe mencionar que se puede combinar definiendo la anotación a nivel de clase y luego en los métodos. El resultado será que la definición a nivel de método sobre escribirá a la de clase.</p>
<p>&nbsp;</p>
<p>El siguiente código es un ejemplo rápido de cómo se apreciaría un EJB con la anotación @TransactionAttribute.</p>
<pre class="lang:java decode:true " title="EmployeeExtendedDAO.java">@EJB
@Stateful
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EmployeeExtendedDAO implements IEmployeeDAO{

    @TransactionAttribute(TransactionAttributeType.NEVER)
    public Employee getEmployeeById(Long empId){
        //Se consulta el empleado mediante el ID
        return manager.find(Employee.class, empId);
    }
}</pre>
<p>&nbsp;</p>
<p>Podrías pensar que configurar las transacciones es muchos más complicado que solo anotar los métodos, pero la realidad es que tan solo eso es necesario, ya que el Application Server se encargará del resto. No voy a entrar un mucho detalle de cómo utilizarlas, pues tan solo es necesario definir la anotación en la clase o en los métodos, el resto queda del lado de EJB, por lo que dejaremos hasta aquí esta sección. y en la siguiente parte hablaremos de cómo gestionar las transacciones con Java SE.</p>
<p>&nbsp;<br />
<center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2017/03/09/jpa-resource-local-transaction/">Siguiente </a></center>		</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/12/20/introduccion-java-transaction-api-jta/">Introducción a Java Transaction API(JTA)</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2016/12/20/introduccion-java-transaction-api-jta/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1316</post-id>	</item>
		<item>
		<title>Operaciones básicas</title>
		<link>https://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/</link>
					<comments>https://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 12 Dec 2016 09:00:06 +0000</pubDate>
				<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">http://www.oscarblancarteblog.com/?p=1110</guid>

					<description><![CDATA[<p>Una parte esencial de utilizar JPA es saber utilizar las operaciones básicas, operaciones mediante las cuales es posible consultar, persistir, actualizar y eliminar entidades, de estas operaciones estaremos hablando hoy. &#160; Gran parte de la funcionalidad de JPA es expuesta por medio de la Interface EntityManager, de la cual ya hemos hablado con anterioridad, y [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/">Operaciones básicas</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>				<img loading="lazy" class="alignleft wp-image-603" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-1024x565.jpg" alt="Operaciones básicas" width="150" height="83" />Una parte esencial de utilizar JPA es saber utilizar las operaciones básicas, operaciones mediante las cuales es posible consultar, persistir, actualizar y eliminar entidades, de estas operaciones estaremos hablando hoy.</p>
<p>&nbsp;</p>
<p>Gran parte de la funcionalidad de JPA es expuesta por medio de la Interface <a href="http://www.oscarblancarteblog.com/2016/10/26/entitymanager-archivo-persistence-xml/" target="_blank">EntityManager</a>, de la cual ya hemos hablado con anterioridad, y es por medio de esta interface, que es posible realizar las operaciones básicas. Las operaciones o métodos que exponen EntityManager son persist, merge, remove, find entre otras, que son sin duda las operaciones que más utilizaremos los proyectos.</p>
<p>En la sección anterior de este tutorial, hablamos de los <a href="http://www.oscarblancarteblog.com/2016/12/05/ciclo-vida-las-entidades/" target="_blank">estados de las entidades</a>, las cuales será clave para entender cómo y cuándo deberemos utilizar dichas operaciones.</p>
<p>&nbsp;</p>
<p>Sin más, las operaciones se describen a continuación:</p>
<p><span id="more-1110"></span></p>
<h2>Método Persist</h2>
<p>Mediante esta operación es posible persistir en la base de datos una nueva (new) Entidad, la cual ha sido creada recientemente o persistir una Entidad que se encuentra en el Persistence Context (Atached).</p>
<p>Esta operación la debemos de utilizar cuando queremos persistir una Entidad que ha sido creada recientemente mediante el operador new, o cuando queremos actualizar una Entidad que fue cargada previamente al Persistence Context o dicho de otra manera, para actualizar una Entidad en estado atached.</p>
<p>Veamos un ejemplo de cómo persistiríamos una nueva Entidad:</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true" title="CreateEmployee.java">package com.obb.jpa.jpaturorial.exercises;

import com.obb.jpa.jpaturorial.entity.Employee;
import com.obb.jpa.jpaturorial.entity.Status;
import com.obb.jpa.jpaturorial.util.EntityManagerUtil;
import java.util.Calendar;
import javax.persistence.EntityManager;

/**
 * @author Oscar Blancarte
 */
public class CreateEmployee {

    public static void main(String[] args) {
        //Create new EntityManager
        EntityManager manager = EntityManagerUtil.getEntityManager();

        //Open Trnsaction
        manager.getTransaction().begin();

        Employee employee = new Employee();
        employee.setName("Oscar Blancarte");
        employee.setRegistDate(Calendar.getInstance());
        employee.setSalary(1000);
        employee.setStatus(Status.ACTIVE);
        
        //Persist Employee
        manager.persist(employee);
       
        //Commit Transaction
        manager.getTransaction().commit();
    }
}</pre>
<p>&nbsp;</p>
<p>En las líneas 16 y 19 creamos el EntityManager y abrimos una nueva transacción, En las líneas 21 a 25, creamos un nuevo Empleado y establecemos sus propiedades, seguido utilizamos la instrucción <span class="lang:java decode:true crayon-inline ">manager.persist(employee)</span>  para marcar la entidad para ser persistida, finalmente en la línea 31 cerramos la transacción. Observemos que tan solo es necesario pasar la Entidad como parámetro para que JPA realice la inserción.</p>
<p>&nbsp;</p>
<h2>Método Merge</h2>
<p>La operación merge es utiliza para actualizar una entidad existente que no pertenece a un Contexto de persistencia. Esta operación la debemos utilizar cuando queremos actualizar una entidad que ya existe en la base de datos, pero por algún motivo, esta no está dentro del Contexto de Persistencia, este escenario se da cuando utilizamos DTO para viajar la información del FrontEnd al BackEnd, en donde convertimos el DTO a una Entidad y esta entidad ya existe en la base de datos. Veamos como utilizamos esta operación:</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true" title="UpdateEmployee.java">package com.obb.jpa.jpaturorial.exercises;

import com.obb.jpa.jpaturorial.entity.Employee;
import com.obb.jpa.jpaturorial.entity.Status;
import com.obb.jpa.jpaturorial.util.EntityManagerUtil;
import java.util.Calendar;
import javax.persistence.EntityManager;

/**
 * @author Oscar Blancarte
 */
public class UpdateEmployee {
    public static void main(String[] args) {
        //Create new EntityManager
        EntityManager manager = EntityManagerUtil.getEntityManager();
        
        //Query Employee by ID
        
        //Open Transaction
        manager.getTransaction().begin();
        
        //Set Employee Status
        Employee employee = new Employee();
        employee.setId(1L);
        employee.setName("Oscar Blancarte");
        employee.setRegistDate(Calendar.getInstance());
        employee.setSalary(1000);
        employee.setStatus(Status.INACTIVE);
        
        //Update Employee Status
        manager.merge(employee);
        
        //Commit changes
        manager.getTransaction().commit();
    }
}</pre>
<p>&nbsp;</p>
<p>Veamos que este ejemplo es prácticamente igual al ejemplo de la operación persist, sin embargo, existe una gran diferencia, en la línea 24 establecemos el ID de la entidad, lo que significa que cuando se realice el Merge, este se realice sobre el mismo registro. La segunda diferencia está en la línea 31, donde utilizamos la operación <span class="lang:java decode:true crayon-inline ">manager.merge(employee)</span> .</p>
<p>&nbsp;</p>
<h2>Método Find</h2>
<p>&nbsp;</p>
<p>Esta operación es básica para buscar una Entidad solamente por su ID, mediante esta operación es posible recuperar la Entidad de la base de datos. Recordemos que una Entidad puede tener un ID de un solo campo o tener una llave compuesta, mediante <span class="lang:java decode:true crayon-inline ">@IdClass</span>  y<span class="lang:java decode:true crayon-inline">@EmbeddedId</span>, cuando se trata de una llave simple, solo será necesario consultar la entidad por el valor de la llave primaria, sin embargo, cuando la llave es compuesta, el parámetro deberá ser del tipo de la llave primaria, es decir de la clase marcada como <span class="lang:java decode:true crayon-inline ">@IdClass</span>  o <span class="lang:java decode:true crayon-inline ">@EmbeddedId</span> . Veamos un ejemplo de cómo quedaría:</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true " title="ReadEmploye.java">package com.obb.jpa.jpaturorial.exercises;

import com.obb.jpa.jpaturorial.entity.Employee;
import com.obb.jpa.jpaturorial.util.EntityManagerUtil;
import javax.persistence.EntityManager;

/**
 * @author Osccar Blancarte
 */
public class ReadEmployee {
    public static void main(String[] args) {
        //Create new EntityManager
        EntityManager manager = EntityManagerUtil.getEntityManager();
        
        //Query Employee by ID
        Employee employee = manager.find(Employee.class, 1);
        
        //Print name of Employee
        System.out.println("Employee name ==&gt; " + employee.getName());
    }
}</pre>
<p>&nbsp;</p>
<p>Veamos que la operación find requiere dos parámetros, el primero es la clase de la entidad que esperamos buscar y el segundo valor es el ID. En este caso se trata de una llave simple, por lo que con mandar el valor 1 será suficiente, sin embargo, como mencione anteriormente, en caso se ser compuesta, deberemos mandar la clase que corresponde con la llave primaría.</p>
<p>Como resultado, la operación find retornara la Entidad con el ID = 1 con todas sus propiedades.</p>
<p>&nbsp;</p>
<h2>Método Remove:</h2>
<p>&nbsp;</p>
<p>La operación remove es muy simple, pues solo es requerido enviar la Entidad que se desea remover. La Entidad tendrá que estar dentro del contexto de persistencia para poder ser eliminada, de lo contrario nos arrojara una excepción. Veamos cómo utilizar esta operación:</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true " title="DeleteEmployee.java">package com.obb.jpa.jpaturorial.exercises;

import com.obb.jpa.jpaturorial.entity.Employee;
import com.obb.jpa.jpaturorial.util.EntityManagerUtil;
import javax.persistence.EntityManager;

/**
 * @author Oscar Blancarte
 */
public class DeleteEmployee {
    public static void main(String[] args) {
        //Create new EntityManager
        EntityManager manager = EntityManagerUtil.getEntityManager();
        
        //Query Employee by ID
        Employee employee = manager.find(Employee.class, 1L);
        
        //Open transaction
        manager.getTransaction().begin();
                
        //Delete Employee
        manager.remove(employee);
        
        //Commit transaction
        manager.getTransaction().commit();
    }
}</pre>
<p>&nbsp;</p>
<p>Lo primero que hacemos es consultar al Empleado mediante el la operación find, esto debidos a que la debemos de tener dentro del contexto de persistencia, seguido en la línea 22 ejecutamos la operación <span class="lang:java decode:true crayon-inline">manager.remove(employee</span>  lo cual provocara que la entidad sea eliminada de la base de datos y del contexto de persistencia.</p>
<p>&nbsp;</p>
<h2>Método Refresh:</h2>
<p>Operación que permite actualizar la Entidad con la base de datos, tan solo es necesario mandar como parámetro la Entidad a actualizar, esto actualizará todos los atributos con los de la base de datos:</p>
<pre class="lang:java decode:true">manager.refresh(employee);</pre>
<p>No regresa nada, pues actualiza la misma entidad que se envió como parámetro.</p>
<p>&nbsp;</p>
<h2>Método Detach:</h2>
<p>Operación que permite sacar una Entidad del Contexto de persistencia. Todo cambio realizado en la entidad será descartado al terminar la transacción.</p>
<pre class="lang:java decode:true">manager.detach(employee);
</pre>
<p>La entidad queda en estado detached una vez ejecutada esta instrucción.</p>
<p>&nbsp;</p>
<h2>Método Clear:</h2>
<p>Limpia el Contexto de Persistencia, por lo que todas las entidades pasarán al estado detached</p>
<pre class="lang:java decode:true">Manager.clear();
</pre>
<p>Todos los cambios realizados en la transacción serán desechados.</p>
<p>&nbsp;</p>
<h2>Método Contains:</h2>
<p>Operación que permite saber si una entidad se encuentra en el Contexto de persistencia. Se envía la Entidad a validar y retorna una booleano, indicando si está o no en el Contexto de Persistencia.</p>
<pre class="lang:java decode:true">boolean exist = manager.contains(employee);
</pre>
<p>&nbsp;</p>
<p>Existen muchas operaciones más que nos proporciona el EntityManager, pero estas las veremos gradualmente durante el desarrollo de este tutorial.</p>
<p><center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/12/05/ciclo-vida-las-entidades/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more " style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/">Siguiente </a></center>		</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/">Operaciones básicas</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1110</post-id>	</item>
		<item>
		<title>Ciclo de vida de las Entidades</title>
		<link>https://www.oscarblancarteblog.com/2016/12/05/ciclo-vida-las-entidades/</link>
					<comments>https://www.oscarblancarteblog.com/2016/12/05/ciclo-vida-las-entidades/#respond</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 05 Dec 2016 09:00:25 +0000</pubDate>
				<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">http://www.oscarblancarteblog.com/?p=1267</guid>

					<description><![CDATA[<p>Entender el ciclo de vida de las Entidades es sin duda uno de los puntos cruciales de JPA, pues entender cómo es que una Entidad es gestionada por EntityManager nos permitirá entender mejor como es que JPA funciona y prevenir muchos errores en tiempo de ejecución. Lo primero que debemos de entender, es que todas [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/12/05/ciclo-vida-las-entidades/">Ciclo de vida de las Entidades</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>				<img loading="lazy" class="alignleft wp-image-603 size-full" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg" alt="Tutorial de JPA persistence.xml" width="150" height="83" /></p>
<p>Entender el ciclo de vida de las Entidades es sin duda uno de los puntos cruciales de JPA, pues entender cómo es que una Entidad es gestionada por EntityManager nos permitirá entender mejor como es que JPA funciona y prevenir muchos errores en tiempo de ejecución.</p>
<p>Lo primero que debemos de entender, es que todas entidades que utilicemos con JPA, serán administradas por el EntityManager, es por este motivo que hemos agregado este esta sección al capítulo de EntityManager.</p>
<p>&nbsp;</p>
<h2>Persistence Context:</h2>
<p>Antes de entrar a los estados de las Entidades es importante entender un nuevo concepto que no hemos analizados en esta guía, se trata del Contexto de persistencia (Persistence Context), este lo podemos ver como contenedor en donde se encuentra todas las Entidades administradas por el EntityManager. Cuando un nuevo EntityManager es creado a través del EntityManagerFactory este le asigna un Unidad de persistencia.<span id="more-1267"></span></p>
<p><figure id="attachment_1265" aria-describedby="caption-attachment-1265" style="width: 648px" class="wp-caption aligncenter"><img loading="lazy" class="wp-image-1265 size-large" src="http://www.oscarblancarteblog.com/wp-content/uploads/2016/12/persistencecontext-1024x642.png" alt="Ciclo de vida de las Entidades" width="648" height="406" /><figcaption id="caption-attachment-1265" class="wp-caption-text">Ciclo de vida de las Entidades</figcaption></figure></p>
<p>Cabe mencionar que el Persistence Context no es un objeto con el cual nosotros interactuaremos, ya que este esta encapsulado dentro de Entity Manager y solo a través de este es posible afectarlo. En la siguiente sección hablaremos de las operaciones que ofrece el Entity Manager y con las cuales es posible afectar a Unidad de persistencia y las entidades.</p>
<h2>Estados de las entidades:</h2>
<p>A medida que trabajamos con las entidades, estas van cambiando de estado, y el estado de estas será utilizado para realizar operaciones en la base de datos. Un aspecto importante cuando utilizamos JPA es que ya no estamos trabajando con sentencias SQL y en su lugar trabajamos con las Entidades y sus estados. Las entidades en JPA puedan pasar por cuatro estados distintos que se pueden ver en la siguiente imagen:</p>
<p><figure id="attachment_1266" aria-describedby="caption-attachment-1266" style="width: 648px" class="wp-caption aligncenter"><img loading="lazy" class="wp-image-1266 size-large" src="http://www.oscarblancarteblog.com/wp-content/uploads/2016/12/lifecicle-1024x510.png" alt="Ciclo de vida de las Entidades" width="648" height="323" /><figcaption id="caption-attachment-1266" class="wp-caption-text">Estados de las Entidades</figcaption></figure></p>
<p>Los cuatro estados son:</p>
<ul>
<li><strong>New:</strong> Estado que tiene una entidad cuando es creada con el operador new, por lo tanto, no existe en la base de datos y no está asociada a un contexto de persistencia. Todas las entidades en estado new no serán afectadas en la base de datos cuando la transacción finalice, pues no está asociado a al Context Persistence.</li>
<li><strong>Manage:</strong> Todas las entidades que están siendo administradas por JPA están en estado manage, lo que indica que son parte de un contexto de persistencia. Aplica para entidades que serán insertadas, actualizadas o fueron obtenidas por el EntityManager como parte de alguna operación SELECT.</li>
<li><strong>Detached:</strong> Las entidades en estado detached, son entidades que si existen en la base de datos, pero por algún motivo no son parte de un contexto de persistencia. Todas las entidades en este estatus no serán afectadas en la base de datos, pues no pertenecen a un Persistence Context</li>
<li><strong>Removed:</strong> Cuando una Entidad es marcada para ser eliminada, pasa automáticamente al estado de Removed. Cando la transacción finaliza, todas las Entidades en este status serán eliminadas de la base de datos y ya no existirán más en el Persistence Context.</li>
</ul>
<p>En la siguiente sección hablaremos de las operaciones básicas que nos permite utilizar el EntityManager y con las cueles es posible mover de estados las entidades. Por lo pronto es importante entender los estados por lo que pueden pasar las entidades para que nos facilite entender las operaciones para buscar, persistir, actualizar y borrar de JPA.</p>
<p><center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/30/atributos-volatiles-transient/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/">Siguiente </a></center>		</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/12/05/ciclo-vida-las-entidades/">Ciclo de vida de las Entidades</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2016/12/05/ciclo-vida-las-entidades/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1267</post-id>	</item>
		<item>
		<title>Trabajar con objetos pesados @Lob</title>
		<link>https://www.oscarblancarteblog.com/2016/11/29/trabajar-objetos-pesados-lob/</link>
					<comments>https://www.oscarblancarteblog.com/2016/11/29/trabajar-objetos-pesados-lob/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 29 Nov 2016 15:00:48 +0000</pubDate>
				<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">http://www.oscarblancarteblog.com/?p=1185</guid>

					<description><![CDATA[<p>JPA nos permite mediante la anotación @Lob mapear con la base de datos objetos pesados, como podría ser imágenes, xml, binarios, cadenas de texto extensas, json, etc. Cualquier objeto que pueda tener un tamaña muy grande o de longitud indefinida. @Lob La anotación @Lob es lo único que se requiere para indicarle a JPA que [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/11/29/trabajar-objetos-pesados-lob/">Trabajar con objetos pesados @Lob</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignleft wp-image-603 size-full" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg" alt="Tutorial de JPA @Lob" width="150" height="83" />JPA nos permite mediante la anotación @Lob mapear con la base de datos objetos pesados, como podría ser imágenes, xml, binarios, cadenas de texto extensas, json, etc. Cualquier objeto que pueda tener un tamaña muy grande o de longitud indefinida.</p>
<h2>@Lob</h2>
<p>La anotación @Lob es lo único que se requiere para indicarle a JPA que ese campo es un objeto pesado y que debe de tratarse como tal. Por lo general se utiliza con los arreglos de bytes, ya que permite almacenar cualquier cosa.</p>
<p>La anotación @Lob no tiene ningún atributo, por lo que solo será necesario definirla para que funcione. Otro punto importante es que esta anotación creará una columna de tipo longblob en mysql y podría variar según el manejador de base de datos utilizados, pero al final siempre será un campo para objetos pesados.</p>
<p>Para poner en práctica esta anotación, retomaremos la entidad Employee, en esta ya habíamos agregado la propiedad <span class="lang:java decode:true crayon-inline">photo</span>  de tipo byte[], en la cual vamos a almacenar la foto del empleado, sin embargo, no habíamos entrado en detalles. La entidad Employee se ve de la siguiente manera:</p>
<p><span id="more-1185"></span></p>
<pre class="lang:java decode:true">package com.obb.jpa.jpaturorial.entity;

import java.util.Calendar;
import java.util.Objects;
import javax.persistence.*;

/**
 * @author Oscar Blancarte
 */
@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;
    
    @Column(name="STATUS", nullable = false, length = 8 )
    @Enumerated(value = EnumType.STRING)
    private Status status;
    
    @Column(name = "PHOTO" ,nullable = true)
    @Basic(optional = false, fetch = FetchType.EAGER)
    @Lob()
    private byte[] photo;
    
    /**
     * GETs and SETs
     */
}</pre>
<p>Observemos que @Lob es mucho más simple de lo que parece, sin embargo, recordemos que siempre serán necesarias las anotaciones @Column &amp; @Basic para definir los atributos de la columna y la estrategia de carga. Por lo general las propiedades marcadas como @Lob son cargadas en la creación del objeto y no siempre es requerido el objeto pesado, por lo que es aconsejable utilizar la anotación @Basic y marcar el atributo como LAZY.</p>
<p><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST, </strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)"><strong>https://codmind.com/courses/jpa</strong></a></p>
<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noopener noreferrer"><img loading="lazy" width="800" height="450" class="wp-image-3085 lazy-loaded" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" sizes="(max-width: 800px) 100vw, 800px" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-768x432.jpg 768w" alt="" data-lazy-type="image" data-src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" data-srcset="" /></a><figcaption><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" alt="👉" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" /><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" alt="👉" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" /> Los invito a mi <a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label="Curso de Mastering JPA (opens in a new tab)">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.<br />
<img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" alt="👈" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" /><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" alt="👈" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" /></figcaption></figure>
<p>Finalmente, la tabla de empleados se vera de la siguiente manera:</p>
<p><img loading="lazy" class="aligncenter wp-image-1176 size-full" src="http://www.oscarblancarteblog.com/wp-content/uploads/2016/11/Table-1.jpg" alt="@lob" width="233" height="191" /></p>
<p><strong>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.</strong></p>
<p><center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/24/estrategias-de-carga-con-basic/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/30/atributos-volatiles-transient/">Siguiente </a></center></p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/11/29/trabajar-objetos-pesados-lob/">Trabajar con objetos pesados @Lob</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2016/11/29/trabajar-objetos-pesados-lob/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1185</post-id>	</item>
		<item>
		<title>Estrategias de carga con @Basic</title>
		<link>https://www.oscarblancarteblog.com/2016/11/24/estrategias-de-carga-con-basic/</link>
					<comments>https://www.oscarblancarteblog.com/2016/11/24/estrategias-de-carga-con-basic/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 24 Nov 2016 09:00:30 +0000</pubDate>
				<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">http://www.oscarblancarteblog.com/?p=1175</guid>

					<description><![CDATA[<p>@Basic es una anotación que nos permite controlar el momento en que una propiedad es cargada desde la base de datos, evitando que traer valores que no son necesario al momento de cargar el objeto. Esta anotación es utilizada generalmente para anotar objetos pesados, como una imagen o un archivo binario. @Basic En JPA existe [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/11/24/estrategias-de-carga-con-basic/">Estrategias de carga con @Basic</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignleft wp-image-603 size-full" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg" alt="Tutorial de JPA @Basic" width="150" height="83" />@Basic es una anotación que nos permite controlar el momento en que una propiedad es cargada desde la base de datos, evitando que traer valores que no son necesario al momento de cargar el objeto. Esta anotación es utilizada generalmente para anotar objetos pesados, como una imagen o un archivo binario.</p>
<h2>@Basic</h2>
<p>En JPA existe dos conceptos que son claves para entender cómo es que JPA carga los objetos desde la base de datos y estos son claves para mejorar el rendimiento de la aplicación, estos conceptos se explican a continuación:</p>
<ul>
<li>Lazy loading (Carga demorada): Los objetos de carga demorada no serán cargados desde la base de datos cuando el objeto sea creado, pero será cargado en cuanto se acceda a la propiedad. De esta manera JPA identifica cuando la propiedad es accedida por primera vez para cargar el valor desde la base de datos.
<ul>
<li>@Basic( fetch = FetchType.LAZY )</li>
</ul>
</li>
<li>Eager loading (Carga ansiosa o temprana): Este es la utilizada por default para la mayoria de las propiedades en JPA, a excepción de las colecciones las cuales las analizaremos mas adelante.
<ul>
<li>@Basic( fetch = FetchType.EAGER )</li>
</ul>
</li>
</ul>
<p><span id="more-1175"></span></p>
<p>Lazy loading se logra mediante la utilización del patrón de diseño <a href="http://www.oscarblancarteblog.com/2014/07/29/patron-de-diseno-proxy/">Proxy</a>, el cual también explico con más detalle en <a href="http://www.oscarblancarteblog.com/libros/introduccion-los-patrones-diseno/">mi libro</a>.</p>
<p>La anotación @Basic define además la propiedad optional, la cual es de tipo booleano, si se le indica true, se decimos a JPA que esta propiedad es opcional y en ella puede haber un valor Null, en caso se ser false, le indicamos que la propiedad siempre deberá tener valor. Esta propiedad es más que nada para ayudar a JPA a optimizar los query para obtener los valores. Pero tendrá que corresponder con la realidad, ya que en caso de marcar que no es opcional y este valor es null en la base de datos JPA marca error.</p>
<p><strong>NOTA:</strong> <span class="lang:java decode:true crayon-inline">optional</span>  es diferente  de <span class="lang:java decode:true crayon-inline">nullable</span>  de <a href="http://www.oscarblancarteblog.com/2016/11/10/definicion-columnas-column/">@Column</a>, pues nullable sirve para definir la estructura de la columna y optional son sugerencias a JPA para optimizar los querys. Nunca debemos de confundir eso.</p>
<p>Un punto importante es que @Basic se puede emplear prácticamente para cualquier como tipos primitivos, clases wrapper, Calendar, enums, Time, Date, Timestamp. byte[], char[], clases que implementan java.lang.Serializable, etc.</p>
<p>Ya con toda la teoría, pasaremos a ponerla en práctica. Retómenos la clase Employee que hemos utilizando en todos el tutorial para agregar una nueva propiedad llamada photo, esta será de tipo bute[] y guardara el binario de la foto del empleado. La foto al ser un campo pesado lo marcaremos como LAZY, para evitar que se cargue al crear el objeto y solo cuando sea necesario se cargue. Por otra parte, la foto del empleado no es obligatoria por lo que definiremos la propiedad optional = true.  Veamos cómo quedaría:</p>
<pre class="lang:java decode:true " title="Employee.java">package com.obb.jpa.jpaturorial.entity;

import java.util.Calendar;
import java.util.Objects;
import javax.persistence.*;

/**
 * @author Oscar Blancarte
 */
@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;
    
    @Column(name="STATUS", nullable = false, length = 8 )
    @Enumerated(value = EnumType.STRING)
    private Status status;
    
    @Column(name = "PHOTO" ,nullable = true)
    @Basic(optional = false, fetch = FetchType.EAGER)
    @Lob()
    private byte[] photo;
    
    /**
     * GETs and SETs
     */
}</pre>
<p>Veamos que la anotación <a href="http://www.oscarblancarteblog.com/2016/11/10/definicion-columnas-column/">@Column</a> se define para indicar el nombre de la columna de la base de datos y está definida la propiedad nullable=true debido a que la foto no es obligatoria. Recordemos la diferencia entre nullable &amp; optional que ya analizamos.</p>
<p><strong>NOTA:</strong> En la siguiente sección describiremos la anotación @Lob, por lo pronto solo dejémosla pasar por alto.</p>
<p><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST, </strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)"><strong>https://codmind.com/courses/jpa</strong></a></p>
<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noopener noreferrer"><img loading="lazy" width="800" height="450" class="wp-image-3085 lazy-loaded" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" sizes="(max-width: 800px) 100vw, 800px" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-768x432.jpg 768w" alt="" data-lazy-type="image" data-src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" data-srcset="" /></a><figcaption><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" alt="👉" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" /><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" alt="👉" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" /> Los invito a mi <a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label="Curso de Mastering JPA (opens in a new tab)">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.<br />
<img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" alt="👈" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" /><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" alt="👈" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" /></figcaption></figure>
<p>Finalmente, y tras ejecutar la aplicación para creer las tablas, veremos que la tabla queda de la siguiente manera:</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-1176" src="http://www.oscarblancarteblog.com/wp-content/uploads/2016/11/Table-1.jpg" alt="@Basic" width="233" height="191" /></p>
<p>La columna PHOTO se ha creado de tipo Longblob debido a que la propiedad es de tipo byte[] y puede ser de gran tamaño.</p>
<p><strong>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.</strong></p>
<p><center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/23/mapeo-fechas-temporal/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more " style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/29/trabajar-objetos-pesados-lob/">Siguiente </a></center></p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/11/24/estrategias-de-carga-con-basic/">Estrategias de carga con @Basic</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2016/11/24/estrategias-de-carga-con-basic/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1175</post-id>	</item>
		<item>
		<title>Mapeo de fechas con @Temporal</title>
		<link>https://www.oscarblancarteblog.com/2016/11/23/mapeo-fechas-temporal/</link>
					<comments>https://www.oscarblancarteblog.com/2016/11/23/mapeo-fechas-temporal/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Wed, 23 Nov 2016 09:00:06 +0000</pubDate>
				<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">http://www.oscarblancarteblog.com/?p=1143</guid>

					<description><![CDATA[<p>Mediante la anotación @Temporal es posible mapear las fechas con la base de datos de una forma simple. Una de las principales complicaciones cuando trabajamos con fecha y hora es determinar el formato empleado por el manejador de base de datos. Sin embargo, esto ya no será más problema con @Temporal. Mediante el uso de [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/11/23/mapeo-fechas-temporal/">Mapeo de fechas con @Temporal</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2><img loading="lazy" class="alignleft wp-image-603 size-full" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg" alt="Tutorial de JPA @Temporal" width="150" height="83" /></h2>
<p style="text-align: justify;">Mediante la anotación @Temporal es posible mapear las fechas con la base de datos de una forma simple. Una de las principales complicaciones cuando trabajamos con fecha y hora es determinar el formato empleado por el manejador de base de datos. Sin embargo, esto ya no será más problema con @Temporal.</p>
<p style="text-align: justify;">Mediante el uso de @Temporal es posible determinar si nuestro atributo almacena Hora, Fecha u Hora y fecha, y es posible utilizar la clase Date o Calendar para estos fines. Yo siempre recomiendo utilizar Calendar, pues tiene muchas más operaciones para manipular fecha y hora.</p>
<p style="text-align: justify;">Se pueden establecer tres posibles valores para la anotación:</p>
<ul>
<li><strong>DATE:</strong> Acotara el campo solo a la Fecha, descartando la hora.
<ul>
<li>@Temporal(TemporalType.DATE)</li>
</ul>
</li>
<li><strong>TIME:</strong> Acotara el campo solo a la Hora, descartando a la fecha.
<ul>
<li>@Temporal(TemporalType.TIME)</li>
</ul>
</li>
<li><strong>TIMESTAMP:</strong> Toma la fecha y hora.
<ul>
<li>@Temporal(TemporalType.TIMESTAMP)</li>
</ul>
</li>
</ul>
<p style="text-align: justify;"><span id="more-1143"></span></p>
<p style="text-align: justify;">Para ejemplificar como utilizar esta anotación retomaremos la Entidad Employee que ya hemos venido utilizando en todo este tutorial. En el pasado ya habíamos agregado un atributo llamado registDate que representaba la fecha de ingreso del empleado, pero no habíamos entrando en detalle, por lo que ahora será tiempo de regresar y analizarlo. Veamos como dejamos la entidad Employee:</p>
<pre class="lang:java decode:true">package com.obb.jpa.jpaturorial.entity;

import java.util.Calendar;
import java.util.Objects;
import javax.persistence.*;

/**
 * @author Oscar Blancarte
 */
@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;
    
    @Column(name="STATUS", nullable = false, length = 8 )
    @Enumerated(value = EnumType.STRING)
    private Status status;
    
    /**
     * GETs and SETs
     */
}</pre>
<p style="text-align: justify;">En este caso hemos determinado que la fecha de ingreso es solo fecha (DATE) puesto que no es de nuestro interés la hora. Observemos también que hemos definido la anotación <a href="http://www.oscarblancarteblog.com/2016/11/10/definicion-columnas-column/">@Column</a> para definir el nombre de la columna contra la que mapea.</p>
<p><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST, </strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)"><strong>https://codmind.com/courses/jpa</strong></a></p>
<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noopener noreferrer"><img loading="lazy" width="800" height="450" class="wp-image-3085 lazy-loaded" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" sizes="(max-width: 800px) 100vw, 800px" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-768x432.jpg 768w" alt="" data-lazy-type="image" data-src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" data-srcset="" /></a><figcaption><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" alt="👉" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" /><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" alt="👉" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" /> Los invito a mi <a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label="Curso de Mastering JPA (opens in a new tab)">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.<br />
<img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" alt="👈" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" /><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" alt="👈" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" /></figcaption></figure>
<p style="text-align: justify;">Veamos cómo quedaría la tabla generada hasta el momento:</p>
<p style="text-align: justify;"><img loading="lazy" class="aligncenter size-full wp-image-1144" src="http://www.oscarblancarteblog.com/wp-content/uploads/2016/11/Tabla.jpg" alt="@Temporal" width="215" height="178" /></p>
<p style="text-align: justify;">Observa la columna REGIST_DATE es de tipo DATE.</p>
<p style="text-align: left;"><strong>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.</strong></p>
<p><center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/14/mapeo-enumeraciones-enumerated/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/24/estrategias-de-carga-con-basic/">Siguiente </a></center></p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/11/23/mapeo-fechas-temporal/">Mapeo de fechas con @Temporal</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2016/11/23/mapeo-fechas-temporal/feed/</wfw:commentRss>
			<slash:comments>22</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1143</post-id>	</item>
		<item>
		<title>JPA y los métodos hashCode &#038; equals</title>
		<link>https://www.oscarblancarteblog.com/2016/11/16/jpa-los-metodos-hashcode-equals/</link>
					<comments>https://www.oscarblancarteblog.com/2016/11/16/jpa-los-metodos-hashcode-equals/#respond</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Wed, 16 Nov 2016 09:00:24 +0000</pubDate>
				<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">http://www.oscarblancarteblog.com/?p=1062</guid>

					<description><![CDATA[<p>Por defecto, todos los objetos en Java heredan de la case Object los métodos hashCode y equals los cuales sirvan para identificar si dos variables hacen referencia al mismo objeto. El comportamiento de facto del método hashCode retorna la posición en memoria de un objeto, y el método equals compara el hashCode de los dos [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/11/16/jpa-los-metodos-hashcode-equals/">JPA y los métodos hashCode &#038; equals</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="size-full wp-image-603 alignleft" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg" alt="Tutorial de JPA persistence.xml" width="150" height="83" />Por defecto, todos los objetos en Java heredan de la case Object los métodos hashCode y equals los cuales sirvan para identificar si dos variables hacen referencia al mismo objeto.<br />
El comportamiento de facto del método hashCode retorna la posición en memoria de un objeto, y el método equals compara el hashCode de los dos objetos evaluados, de esta forma, si las dos variables hacen referencia a la misma posición de memoria, entonces se dice que son igual, de lo contrario son diferentes.<br />
En el caso de las Entidades, la implementación default de estos métodos no funciona correctamente, debido a que una Entidad de dice que es igual a otra si se cumplen dos condiciones:</p>
<p>• Los dos objetos son de la misma clase.<br />
• El valor de su ID (@Id) son iguales</p>
<p>Si estas dos condiciones se cumplen entonces las dos entidades son iguales sin importar que no hagan referencia a mismo objeto en memoria. Debido a esto, es que es importante sobrescribir estos dos métodos para que evalúen a una Entidad por las dos condiciones mencionadas.</p>
<h2>Implementando los métodos hashCode &amp; equals</h2>
<p>Algo que me ha llamado mucho la atención es que a pesar de que estos dos métodos son básicos y que se utilizan con regularidad, muchas personas no entienden como trabajan internamente y aún menos como sobrescribirlos correctamente, si eres una de esas personas, no te preocupes ya que los IDE’s ya tiene por default utilidades que nos ayudan a generarlos de forma adecuada.<br />
Lo primero que haremos será abrir la entidad Employee que hemos venido trabajando a lo largo de este tutorial. Luego presionaremos Source &gt; Insert Code del menú principal, esto arrojara una pequeña lista de acciones, seleccionamos la opción equals() and hashCode(). Nos arrojara una pantalla como la siguiente:<br />
<img loading="lazy" class="aligncenter size-full wp-image-1063" src="http://www.oscarblancarteblog.com/wp-content/uploads/2016/10/generateEqualsyHashcode.png" alt="Método equals y hashcode" width="550" height="342" /><span id="more-1062"></span><br />
En esta pantalla debemos todos los campos que conformen el ID de la Entidad, en este caso solo sería el atributo ID, lo seleccionamos en las dos listas como aparece en la imagen anterior, y presionamos generate. Esto concluirá la generación de los dos métodos y se deberán de ver así:</p>
<pre class="lang:java decode:true">package com.obb.jpa.jpaturorial.entity;

import java.util.Objects;
import javax.persistence.*;

/**
 * @author Oscar Blancarte
 */
@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;
    private String name; 

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 29 * hash + Objects.hashCode(this.id);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Employee other = (Employee) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

     /**
     * GETs and SETs
     */
}</pre>
<p>El método hashCode regresará un hash generado a partir del ID, veamos que en la ecuación interviene un variable hash con valor 7. No te preocupes por eso, es solo un número generado al azar.</p>
<p><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST, </strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)"><strong>https://codmind.com/courses/jpa</strong></a></p>
<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noopener noreferrer"><img loading="lazy" width="800" height="450" class="wp-image-3085 lazy-loaded" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" sizes="(max-width: 800px) 100vw, 800px" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-768x432.jpg 768w" alt="" data-lazy-type="image" data-src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" data-srcset="" /></a><figcaption><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" alt="👉" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" /><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" alt="👉" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f449.svg" /> Los invito a mi <a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener" aria-label="Curso de Mastering JPA (opens in a new tab)">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.<br />
<img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" alt="👈" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" /><img class="emoji lazy-loaded" draggable="false" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" alt="👈" data-lazy-type="image" data-src="https://s.w.org/images/core/emoji/11.2.0/svg/1f448.svg" /></figcaption></figure>
<p>Por otra parte el método equals lo primero que hará será comparar los dos objetos con el operador ==, este operador se traduce en la llamada del método hashCode de tal manera que this == obj sería igual a this.hashCode() == obj.hashCode(), y como va vimos el hashCode se genera a partir del ID y no a la posición de memoria, por tal motivo la expresión solo sería verdadera en caso de ambos objetos tengan el mismo ID.</p>
<p><strong>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.</strong></p>
<p><center><a class="btn btn-default read-more " style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/02/llaves-compuestas-idclass/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/2016/11/08/embeber-llave-primaria-embeddedid/">Siguiente </a></center></p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2016/11/16/jpa-los-metodos-hashcode-equals/">JPA y los métodos hashCode &#038; equals</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2016/11/16/jpa-los-metodos-hashcode-equals/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1062</post-id>	</item>
	</channel>
</rss>
