<?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/"
	>

<channel>
	<title>Hibernate &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<atom:link href="https://www.oscarblancarteblog.com/category/hibernate/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.oscarblancarteblog.com</link>
	<description>Software Architect &#38; FullStack developer</description>
	<lastBuildDate>Tue, 10 Nov 2020 04:52:49 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://www.oscarblancarteblog.com/wp-content/uploads/2019/03/cropped-ob-32x32.png</url>
	<title>Hibernate &#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>Relaciones @OneToMany</title>
		<link>https://www.oscarblancarteblog.com/2018/12/20/relaciones-onetomany/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/20/relaciones-onetomany/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 20 Dec 2018 16:00:27 +0000</pubDate>
				<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2555</guid>

					<description><![CDATA[Las relaciones uno a muchos (@OneToMany) se caracterizan por Entidad donde tenemos un objeto principal y colección de objetos de otra Entidad relacionados directamente. Estas relaciones se definen mediante colecciones, pues tendremos una serie de objetos pertenecientes al objeto principal. Este articulo es parte de un guia completa de JPA, para ver el contenido completo [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/jpa-onetomany-1024x575.jpg" alt="JPA relaciones @OneToMany" class="wp-image-2556"/></figure>



<p class="wp-block-paragraph">Las relaciones uno a muchos (@OneToMany) se caracterizan por Entidad donde tenemos un objeto principal y  colección de objetos de otra Entidad relacionados directamente. Estas relaciones se definen mediante colecciones, pues tendremos una serie de objetos pertenecientes al objeto principal.<br><br></p>



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



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Este articulo es parte de un guia completa de JPA, para ver el contenido completo puedes ir a <a href="https://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Java Persistence API (JPA)</a></p></blockquote>



<p class="wp-block-paragraph"><br>Un ejemplo clásico para entender este tipo de relaciones son las facturas, pues tendremos una Entidad cabecera donde tengamos los datos principales de la factura, como podría ser serie, cliente, total, fecha de expedición, etc. Por otra parte, la factura tendrá una serie de líneas que representa cada uno de los productos vendidos.&nbsp;</p>



<p class="wp-block-paragraph">Veamos como quedaría la entidad <code>Invoice</code> (factura):</p>



<pre class="wp-block-code"><code class="">package com.obb.jpa.jpaturorial.entity;

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

@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;
    
    @JoinColumn(name = "FK_CUSTOMER", nullable = false)
    @ManyToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Customer customer;
    
    @OneToOne(mappedBy = "invoice", cascade = CascadeType.ALL)
    private Payment payment;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "invoice")
    private List&lt;InvoiceLine> lines;

    /** GET and SET */
}</code></pre>



<p class="wp-block-paragraph"><br>Podemos apreciar como hemos definido la propiedad lines como una lista (<code>List</code>), lo cual nos permite relacionar la factura con un número indeterminado de líneas, por otro lado, hemos definido la propiedad <code>mappedBy</code> para indicar que es una relación bidireccional, es decir, la Entidad <code>InvoiceLine</code> tendrá también una relación hacia la Entidad <code>Invoice</code>.</p>



<p class="wp-block-paragraph">La Entidad <code>InvoiceLine</code> se verá de la siguiente manera:</p>



<pre class="wp-block-code"><code class="">package com.obb.jpa.jpaturorial.entity;

import javax.persistence.*;

@Entity
@Table(name = "invoice_lines")
public class InvoiceLine {
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "PRODUCT", nullable = false)
    private String product;
    
    @Column(name = "PRICE", nullable = false)
    private double price;
    
    @Column(name = "TOTAL", nullable = false)
    private double quantity;
    
    @ManyToOne
    @JoinColumn(name = "FK_INVOICE", nullable = false, updatable = false)
    private Invoice invoice;
    
    /** GET and SET */

}</code></pre>



<p class="wp-block-paragraph"><br>Como dijimos hace un momento, la Entidad <code>InvoiceLine</code> tiene una propiedad de tipo <code>Invoice</code> para poderla hacer bidireccional, observemos que el nombre de la propiedad <code>invoice</code> corresponde con el valor del <code>mappedBy</code> definido en la Entidad <code>Invoice</code>, ya que de lo contrario JPA nos arrojará un error.</p>



<p class="wp-block-paragraph"><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST,&nbsp;</strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener"><strong>https://codmind.com/courses/jpa</strong></a></p>



<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener"><img fetchpriority="high" decoding="async" width="800" height="450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" alt="" class="wp-image-3085" 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" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>&nbsp;Los invito a mi&nbsp;<a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.<br></figcaption></figure>



<p class="wp-block-paragraph"><br>En este imagen podemos apreciar que la tabla <em>invoice_lines</em> tiene la columna <em>FK_INVOICE</em> que será utilizada para realizar el <em>JOIN</em> con la tabla <em>invoices</em>, de tal forma que cada registro de <em>invoice_lines</em> que sea encontrado será convertido en una instancia de la Entidad <code>InvoiceLine</code>.</p>



<pre class="wp-block-code"><code class="">public static void main(String[] args) {
    Invoice invoice = new Invoice();

    List&lt;InvoiceLine> lines = new ArrayList&lt;>();
    for(int c = 0; c&lt;10; c++){
        InvoiceLine line = new InvoiceLine();
        line.setInvoice(invoice);
        line.setPrice(10);
        line.setProduct("Product " + (c+1));
        line.setQuantity(c+1);
        lines.add(line);
    }

    Customer customer = new Customer();
    customer.setName("Oscar Blancarte");

    invoice.setCustomer(customer);
    invoice.setLines(lines);
    invoice.setRegistDate(Calendar.getInstance());
    invoice.setStatus(Status.ACTIVE);

    EntityManager em = EntityManagerUtil.getEntityManager();
    em.getTransaction().begin();
    em.persist(invoice);
    em.getTransaction().commit();
}</code></pre>



<p class="wp-block-paragraph"><br>Dando como resultado los siguientes registros en la base de datos:</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoices-select-1.jpg" alt="JPA relaciones @OneToMany tabla invoices" class="wp-image-2558"/><figcaption>Tabla invoices</figcaption></figure></div>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoice-lines-select.jpg" alt="JPA relaciones @OneToMany tabla invoice_lines" class="wp-image-2559"/><figcaption>Tabla invoice_lines</figcaption></figure></div>



<p class="wp-block-paragraph">Ahora si podemos ver todo materializado y nos queda más la forma en que la información es almacenada.&nbsp;<br><br><br></p>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">Hemos comprobado lo simple que es crear relaciones <code>@OneToMany</code> y hemos podido comprobar como&nbsp; la información es almacenada, solo faltaría resaltar que JPA no garantiza el orden en que los elementos de la colección son insertados, es por ello, que siempre se aconseja tener una columna que indique el orden natural de los elementos para sobre esa columna hacer el ordenamiento, esto claro si nos interesa mantener el ordenamiento, en caso podemos ignorarlo.</p>



<center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2018/12/14/relaciones-onetoone/">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/27/relaciones-manytomany/">Siguiente </a></center>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2018/12/20/relaciones-onetomany/feed/</wfw:commentRss>
			<slash:comments>18</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2555</post-id>	</item>
		<item>
		<title>Relaciones @OneToOne</title>
		<link>https://www.oscarblancarteblog.com/2018/12/14/relaciones-onetoone/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/14/relaciones-onetoone/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Fri, 14 Dec 2018 16:00:51 +0000</pubDate>
				<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2499</guid>

					<description><![CDATA[Las relaciones One to One (@OneToOne) se caracterizan porque solo puede existir una y solo una relación con la Entidad de destino, de esta forma, la entidad marcada como @OnoToOne deberá tener una referencia a la Entidad destino y por ningún motivo podrá ser una colección. De la misma forma, la Entidad destino no podrá [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/jpa-onetoone-1024x575.jpg" alt="" class="wp-image-2500"/></figure>



<p class="wp-block-paragraph">Las relaciones One to One (<em>@OneToOne</em>) se caracterizan porque solo puede existir una y solo una relación con la Entidad de destino, de esta forma, la entidad marcada como <em>@OnoToOne</em> deberá tener una referencia a la Entidad destino y por ningún motivo podrá ser una colección. De la misma forma, la Entidad destino no podrá pertenecer a otra Instancia de la Entidad origen.</p>



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



<p class="wp-block-paragraph">Solo para ponernos en contexto, las relaciones <code>@OneToOne</code> se utilizan cuando existe una profunda relación entre la Entidad origen y destino,de tal forma que la entidad destino le pertenece a la Entidad origen y solo a ella, por ende, la existencia de la entidad destino depende de la Entidad origen.</p>



<p class="wp-block-paragraph">Para comprender mejor todo este trabalenguas, analicemos el caso práctico de una factura, cuando creamos una factura, la llevamos con nuestro cliente para que la pague, este pago puede ser una entidad por separada que lleve el control de la fecha de pago, monto pagado, método de pago, etc. Veamos como quedarían esta Entidades</p>



<p class="wp-block-paragraph"><strong>Entidad Invoice:</strong></p>



<pre class="wp-block-code"><code class="">package com.obb.jpa.jpaturorial.entity;

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

@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;
    
    @JoinColumn(name = "FK_CUSTOMER", nullable = false)
    @ManyToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Customer customer;
    
    @OneToOne(mappedBy = "invoice", cascade = CascadeType.ALL)
    private Payment payment;

    /** GET and SET */
    
}</code></pre>



<p class="wp-block-paragraph"><strong>Entidad Payment:</strong></p>



<pre class="wp-block-code"><code class="">package com.obb.jpa.jpaturorial.entity;

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

/**
 * @author Oscar Blancarte &lt;oscarblancarte3@gmail.com>
 */
@Entity
@Table(name = "payments")
public class Payment {
    
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="PAY_DATE", nullable = false, updatable = false)
    private Calendar payDate;
    
    @Column(name = "AMOUNT", nullable = false, updatable = false)
    private double amount;
    
    @Column(name = "PAY_METHOD", nullable = false, updatable = false)
    private PaymentMethod paymentMethod;
    
    @OneToOne
    @JoinColumn(name = "FK_INVOICE", updatable = false, nullable = false)
    private Invoice invoice;

    /** GET and SET */
}</code></pre>



<p class="wp-block-paragraph">Estas dos Entidades
crearán las siguientes tablas:</p>



<figure class="wp-block-image"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/onetoone-table.jpg" alt="" class="wp-image-2508"/></figure>



<p class="wp-block-paragraph">Como podemos observar, la tabla <em>payments </em>tiene la columna <em>FK_INVOICE</em> que hace relación con la tabla invoices. </p>



<p class="wp-block-paragraph"><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST,&nbsp;</strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener"><strong>https://codmind.com/courses/jpa</strong></a></p>



<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener"><img decoding="async" width="800" height="450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" alt="" class="wp-image-3085" 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" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>&nbsp;Los invito a mi&nbsp;<a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.<br></figcaption></figure>



<p class="wp-block-paragraph">Algo que hay que tomar en cuenta, es que tanto la Entidad <code>Invoice</code> como <code>Payment</code> tiene anotada como <code>@OneToOne</code> a la otra entidad, sin embargo, solo payments ha creado la columna para hacer el JOIN, esto se debe a que esta es la que tiene la anotación <code>@JoinColumn</code>, la cual nos permite establecer como se llamará la columna para realizar el JOIN, adicional, la Entidad <code>Invoice</code> tiene definida la propiedad <code>mappedBy</code> de la anotación <code>@OneToOne</code>, esta propiedad es muy importante, pues le permite hacer una relación bidireccional, si no la pusiéramos, JPA agregaría una columna adicional en la tabla <em>invoices</em>, y guardaría el pago como un nuevo registro.</p>



<p class="wp-block-paragraph">Veamos un ejemplo de cómo se crearía un registro con esta relación:</p>



<pre class="wp-block-code"><code class="">public static void main(String[] args) {
        EntityManager manager = EntityManagerUtil.getEntityManager();
        
        Customer customer = new Customer();
        customer.setName("Oscar Blancarte");
        
        Payment payment = new Payment();
        payment.setAmount(100);
        payment.setPayDate(Calendar.getInstance());
        payment.setPaymentMethod(PaymentMethod.CASH);
                
        
        Invoice invoice = new Invoice();
        invoice.setCustomer(customer);
        invoice.setRegistDate(Calendar.getInstance());
        invoice.setStatus(Status.ACTIVE);
        
        payment.setInvoice(invoice);
        invoice.setPayment(payment);
        
        manager.getTransaction().begin();
        manager.persist(invoice);
        manager.getTransaction().commit();
    }</code></pre>



<p class="wp-block-paragraph">Dando como resultado lo siguiente:</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/payments-table.jpg" alt="JPA OneToOne payments table" class="wp-image-2509"/><figcaption>Tabla payments</figcaption></figure></div>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoices-table.jpg" alt="JPA OneToOne invoices table" class="wp-image-2510"/><figcaption>Tabla invoices</figcaption></figure></div>



<h2 class="wp-block-heading">Conclusiones</h2>



<p class="wp-block-paragraph">Crear relaciones OneToOne es muy simple como hemos podido comprobar, e incluso, podríamos crear una relación unidireccionar omitiendo la propiedad payment de la entidad <code>Invoice</code>, lo que diera como resultado exactamente la misma estructura de base de datos, con la única limitante que no podríamos recuperar el pago por medio de la factura y es por ello que utilizamos relacionar bidireccionales con <code>mappedBy</code>.<br><br></p>



<center><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/">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/20/relaciones-onetomany/">Siguiente </a></center>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2018/12/14/relaciones-onetoone/feed/</wfw:commentRss>
			<slash:comments>24</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2499</post-id>	</item>
		<item>
		<title>Personalizar las relaciones con @JoinColumn</title>
		<link>https://www.oscarblancarteblog.com/2018/12/13/personalizar-las-relaciones-con-joincolumn/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/13/personalizar-las-relaciones-con-joincolumn/#respond</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 13 Dec 2018 16:00:49 +0000</pubDate>
				<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2469</guid>

					<description><![CDATA[Mediante la anotación @JoinColumn es posible personalizar las columnas que será utilizadas como uniones con otras tablas. Cuando trabajamos con relaciones como @ManyToOne o @OneToOne, es necesario indicarle a JPA como es que tendrá que realizar la unión (JOIN) con la otra Entidad.   Nota: Este artículo pertenece a un tutorial completo de JPA, el [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" class="aligncenter size-large wp-image-2477" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/jpa-joincolumn-1024x575.jpg" alt="JPA anotación @JoinColumn" width="648" height="364" />Mediante la anotación @JoinColumn es posible personalizar las columnas que será utilizadas como uniones con otras tablas. Cuando trabajamos con relaciones como @ManyToOne o @OneToOne, es necesario indicarle a JPA como es que tendrá que realizar la unión (JOIN) con la otra Entidad.<span id="more-2469"></span></p>
<p> </p>
<blockquote>
<p>Nota: Este artículo pertenece a un tutorial completo de JPA, el cual puedes <a href="https://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">ver aquí</a>.</p>
</blockquote>
<p> </p>
<p>La anotación <span class="lang:default decode:true crayon-inline ">@JoinColumn</span>  se puede llegar a confundir con <span class="lang:default decode:true crayon-inline ">@Column</span> , sin embargo, tiene una funcionalidad diferente, <span class="lang:default decode:true crayon-inline ">@JoinColumn</span>  se utiliza para marcar una propiedad la cual requiere de un JOIN para poder accederlas, mientas que <span class="lang:default decode:true crayon-inline ">@Column</span>  se utiliza para representar columnas simples que no están relacionadas con otra Entidad. A pesar de que se utiliza para cosas distintas, la realidad es que se parecen muchísimo, pues tiene casi las mismas propiedades, por que podríamos decir que <span class="lang:default decode:true crayon-inline ">@JoinColumn</span>  es el equivalente de <span class="lang:default decode:true crayon-inline ">@Column</span>  cuando utilizamos relaciones con Entidades.</p>
<p> </p>
<p>En la entrada pasada de este tutorial explicamos el caso de la Entidad Factura (<span class="lang:default decode:true crayon-inline ">Invoice</span> ) y Cliente (<span class="lang:default decode:true crayon-inline ">Customer</span> ), donde dijimos que toda factura está relacionada a un cliente, y utilizamos la anotación <span class="lang:default decode:true crayon-inline ">@ManyToOne</span>  para crear la relación, recordemos como quedaron estas Entidades:</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>Entidad Customer:</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>Podemos ver claramente que la Entidad <span class="lang:default decode:true crayon-inline ">Invoice</span>  tiene una relación <span class="lang:default decode:true crayon-inline ">@ManyToOne</span>  con la Entidad <span class="lang:default decode:true crayon-inline ">Customer</span> , esto le indica a JPA que requerirá hacer un <em>JOIN</em> para poder recuperar al Cliente, sin embargo, no hemos definido la anotación <span class="lang:default decode:true crayon-inline ">@JoinColumn</span>  y aun así trabaja, ¿cómo es esto posible?</p>
<p>Para comprender esto mejor, será necesario ver como JPA auto creo las tablas al momento de crear el schema, veamos las tablas generadas:</p>
<p><img loading="lazy" decoding="async" 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>Podemos ver claramente que JPA creo la columna <em>CUSTOMER_ID</em> en la tabla <em>invoices</em>, pero no solo eso, si no que además, creo por nosotros la llave foránea, esto nos puede hacer pensar que la anotación <span class="lang:default decode:true crayon-inline ">@JoinColumn</span>  no es necesaria, y pueda que tengas razón, sin embargo, no utilizarla nos dejará a merced de como JPA genere la columna y como realice el JOIN con la tabla de empleados, lo cual será un verdadero problema si el Schema ya existe, pues muy probablemente la consulta falle al buscar la columna con un nombre diferente del que JPA asumiría.</p>
<p> </p>
<p>Ahora bien, con <span class="lang:default decode:true crayon-inline ">@JoinColumn</span> , podría definir el nombre exacto de la columna, si admite nulos, si es actualizable, insertable, indicar si queremos que genere o no la llave foránea o incluso, podríamos decirle sobre que Tabla debe generar el Join. Mejor veamos como quedaría la Entidad <span class="lang:default decode:true crayon-inline ">Invoice</span>  utilizando la anotación <span class="lang:default decode:true crayon-inline ">@JoinColumn</span> :</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;
    
    @JoinColumn(name = "fk_customer", nullable = false)
    @ManyToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Customer customer;
 
    /** GET and SET */
}</pre>
<p> </p>
<p>Ahora veamos como quedaría la nueva tabla <em>invoices</em>:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-2474" src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/tables.jpg" alt="" width="552" height="237" /></p>
<p>En esta segunda tabla ya vemos que ha cambiado el nombre de la columna, adicional se ha creado el constraint para no permitir valores nulos, aun que esto último no se pueda ver en la imagen.</p>
<p> </p>
<h2>Propiedades de @JoinColumn</h2>
<p>Ahora pasemos a analizar las propiedades que nos brinda <span class="lang:default decode:true crayon-inline ">@JoinColumn</span> :</p>
<ul>
<li><strong>name</strong>: Indica el nombre con el que se deberá de crear la columna dentro de la tabla.</li>
<li><strong>referencedColumnName</strong>: Se utiliza para indicar sobre que columna se realizará el Join de la otra tabla. Por lo general no se suele utilizar, pues JPA asume que la columna es el ID de la Entidad objetivo.</li>
<li><strong>unique</strong>: Crea un constraints en la tabla para impedir valores duplicados (default false).</li>
<li><strong>nullable</strong>: Crea un constraints en la tabla para impedir valores nulos (default true).</li>
<li><strong>insertable</strong>: Le indica a JPA si este valor deberá guardarse en la operación de inserción (default true)</li>
<li><strong>updatable</strong>: Le indica a JPA si el valor deberá actualizarse durante el proceso de actualización (default true)</li>
<li><strong>columnDefinition</strong>: Esta propiedad es utiliza para indicar la instrucción SQL que se deberá utilizar la crear la columna en la base de datos. Esta nos ayuda a definir exactamente como se creará la columna sin depender de la configuración de JPA.</li>
<li><strong>table</strong>: Le indicamos sobre que tabla deberá realizar el JOIN, normalmente no es utilizada, pues JPA asume la tabla por medio de la entidad objetivo.</li>
<li><strong>foreignKey</strong>: Le indica a JPA si debe de crear el Foreign Key, esta propiedad recibe uno de los siguientes valores <span class="lang:default decode:true crayon-inline ">CONSTRAINT</span> , <span class="lang:default decode:true crayon-inline ">NO_CONSTRAINT</span> , <span class="lang:default decode:true crayon-inline">PROVIDER_DEFAULT</span>  definidos en la enumeración <span class="lang:default decode:true crayon-inline ">javax.persistence.ForeignKey</span> .</li>
</ul>
<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" decoding="async" width="800" height="450" class="wp-image-3085 lazy-loaded" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" sizes="auto, (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 decoding="async" 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 decoding="async" 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 decoding="async" 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 decoding="async" 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> </p>
<h2>Conclusiones</h2>
<p>Hemos podido analizar como es que JPA se apoya de <span class="lang:default decode:true crayon-inline ">@JoinColumn</span>  para permitirle al programador personalizar cada aspecto de la columna de unión, lo cual es bastante bueno para poder respetar los estándares o nomenclaturas que usamos en nuestra empresa o proyecto. Como recomendación, yo siempre insisto en definir estas anotaciones, pues no es conveniente quedarnos a merced de la implementación de JPA para que defina como crear nuestras columnas.</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/2018/12/06/relacion-muchos-a-uno-con-manytoone/">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/14/relaciones-onetoone/">Siguiente </a></center>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2018/12/13/personalizar-las-relaciones-con-joincolumn/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2469</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[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;]]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" 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" decoding="async" 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" decoding="async" 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" decoding="async" 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" decoding="async" 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" decoding="async" 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" decoding="async" 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" decoding="async" width="800" height="450" class="wp-image-3085 lazy-loaded" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" sizes="auto, (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>
]]></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>Store Procedure con parámetros de salida</title>
		<link>https://www.oscarblancarteblog.com/2014/09/03/hibernate-store-procedure-con-parametros-de-salida/</link>
					<comments>https://www.oscarblancarteblog.com/2014/09/03/hibernate-store-procedure-con-parametros-de-salida/#respond</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Wed, 03 Sep 2014 16:46:48 +0000</pubDate>
				<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">http://oscarblancarteblog.com/2014/09/03/hibernate-store-procedure-con-parametros-de-salida/</guid>

					<description><![CDATA[Es esta entrada les quiero compartir como invocar un Store Procedure con Parametros de Salida y recuperarlos por medio de Hibernate. Es ejemplo lo realizo con la Base de datos Oracle 11g XE y con la versión de Hibernate 4.3. Codigo del Store Procedure. &#160; A continuación el código con la explicación: package com.oscarblancarte.hibernate; import [&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://www.oscarblancarteblog.com/wp-content/uploads/2014/09/Hibernate-logo1-e1429932456458.png"><img loading="lazy" decoding="async" class=" wp-image-575 alignleft" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/09/Hibernate-logo1-e1429932456458.png" alt="Hibernate-logo" width="100" height="100" /></a>Es esta entrada les quiero compartir como invocar un Store Procedure con Parametros de Salida y recuperarlos por medio de Hibernate.</p>
<p style="text-align: justify;">Es ejemplo lo realizo con la Base de datos Oracle 11g XE y con la versión de Hibernate 4.3.<span id="more-365"></span></p>
<h2><strong>Codigo del Store Procedure.</strong></h2>
<p><figure id="attachment_364" aria-describedby="caption-attachment-364" style="width: 490px" class="wp-caption aligncenter"><a href="http://www.oscarblancarteblog.com/wp-content/uploads/2014/09/spscript.png"><img loading="lazy" decoding="async" class="wp-image-364 size-full" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/09/spscript.png" alt="Store Procedure" width="490" height="76" /></a><figcaption id="caption-attachment-364" class="wp-caption-text">Fig. 1: Codigo del SP</figcaption></figure></p>
<p>&nbsp;</p>
<h2><strong>A continuación el código con la explicación:</strong></h2>
<pre class="lang:java decode:true" title="HibernateProcedure.java">package com.oscarblancarte.hibernate;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.persistence.ParameterMode;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.service.ServiceRegistry;

public class HibernateProcedure {

	private static final SessionFactory sessionFactory = buildSessionFactory();

	public static void main(String[] args) {
		// Obtenemos la session
		Session session = getSessionFactory().getCurrentSession();

		// Abrimos transacción &lt;OPCIONAL&gt;
		session.beginTransaction();

		// Nombre del SP
		ProcedureCall call = session.createStoredProcedureCall("PROC1");
		// Registramos el primer parametros de entrada
		call.registerParameter(1, String.class, ParameterMode.IN);
		// Registramos el segundo parametro de salida
		call.registerParameter(2, Integer.class, ParameterMode.OUT);

		//Establecemos el valor del primer parametros de entrada
		call.getParameterRegistration(1).bindValue("hola");
		//Ejecutamos el SP y obtenemos el parametro 2, el cual es de salida(out)
		Object salida = call.getOutputs().getOutputParameterValue(2);
		//Se imprime el parametro de salida
		System.out.println("SALIDA ==&gt; " + salida.toString());

		// cerramos transacción &lt;OPCIONAL&gt;
		session.getTransaction().commit();
		System.out.println("FIN");
	}

	private static SessionFactory buildSessionFactory() {
		try {
			Configuration configuration = new Configuration();
			configuration.configure("hibernate.cfg.xml");
			ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
					.applySettings(configuration.getProperties()).build();
			SessionFactory sessionFactory = configuration
					.buildSessionFactory(serviceRegistry);
			return sessionFactory;
		} catch (Throwable ex) {
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}</pre>
<p style="text-align: justify;">La clave es registrar adecuadamente los parámetros, registrando su tipo de dato y Mode el cual puede ser de entrada o salida.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2014/09/03/hibernate-store-procedure-con-parametros-de-salida/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">365</post-id>	</item>
		<item>
		<title>JPA, Hibernate VS JDBC</title>
		<link>https://www.oscarblancarteblog.com/2014/07/15/jpa-hibernate-vs-jdbc/</link>
					<comments>https://www.oscarblancarteblog.com/2014/07/15/jpa-hibernate-vs-jdbc/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 15 Jul 2014 22:00:39 +0000</pubDate>
				<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[JDBC]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[objeto relacional]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[POO]]></category>
		<category><![CDATA[Programación orientada a objetos]]></category>
		<guid isPermaLink="false">http://javamex.wordpress.com/2014/07/15/jpa-hibernate-vs-jdbc/</guid>

					<description><![CDATA[Los que ya han tenido la oportunidad de trabajar con algún ORM como JPA o Hibernate sabrán las bondades que tiene ya que nos permite desarrollar de una forma mucho mas rápida y con muchos menos errores en tiempo de ejecución ya que nos permite modelar nuestras entidad como Clases Java las cuales serán convertidas [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>				<a href="http://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg"><img loading="lazy" decoding="async" class="size-full wp-image-603 alignleft" src="http://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg" alt="JPA HIBERNATE JDBC" width="150" height="83" /></a>Los que ya han tenido la oportunidad de trabajar con algún ORM como JPA o Hibernate sabrán las bondades que tiene ya que nos permite desarrollar de una forma mucho mas rápida y con muchos menos errores en tiempo de ejecución ya que nos permite modelar nuestras entidad como Clases Java las cuales serán convertidas a las instrucciones Insert, Update o Select según sea la operación a realizar. Claro que todas estos beneficios tiene un costo y es que el performance se degrada debido a todas las conversiones que se tiene que hacer para convertir las Entity en Querys y los ResultSet pasarlos a clases ademas que cada registro representa un Objeto en memoria que tendrá <span id="more-24"></span>que ser administrador por nuestra servidor.</p>
<p>Por otro lado tenemos a JDBC que nos brinda total libertad de hacer lo que queramos sin ningún tipo de limitación explotando al máximo las características de la base datos. JDBC nos permite realizar consultas nativas para cada base de datos lo que ayuda mucho a la velocidad de respuesta y los resultados son devueltos en un ResultSet los cuales podemos extraer solamente los datos que requerimos y no toda la Entity como en el caso de JPA o Hibernate.</p>
<p>&nbsp;</p>
<h2><strong>JPA,Hibernate</strong></h2>
<p>Ventajas</p>
<ol>
<li>Nos permite desarrollar mucho mas rápido.</li>
<li>Permite trabajar con la base de datos por medio de entidades en vez de Querys.</li>
<li>Nos ofrece un paradigma 100% orientado a objetos.</li>
<li>Elimina errores en tiempo de ejecución.</li>
<li>Mejora el mantenimiento del software.</li>
</ol>
<p>Desventajas</p>
<ol>
<li>No ofrece toda la funcionalidad que ofrecería tirar consultas nativas.</li>
<li>El performance es mucho mas bajo que realizar las consultas por JBDC.</li>
<li>Puede representar una curva de aprendizaje mas grande.</li>
</ol>
<p>&nbsp;</p>
<h2><strong>JDBC</strong></h2>
<p>Ventajas</p>
<ul>
<li>Ofrece un performance superior ya que es la forma mas directa de mandar instrucciones la base de datos.</li>
<li>Permite explotar al máximo las funcionalidades de la base de datos.</li>
</ul>
<p>Desventajas</p>
<ul>
<li>El mantenimiento es mucho mas costoso.</li>
<li>Introduce muchos errores en tiempo de ejecución.</li>
<li>El desarrollo es mucho mas lento.</li>
</ul>
<p>&nbsp;</p>
<p>Probablemente pensaras que JPA o Hibernate son mejores ya que ofrece mayor ventajas que desventajas sin embargo las desventajas que tiene son muy serias y pueden ser cruciales a la hora de decidir que tecnología utilizar ya que si tenemos una aplicación muy buena y fácil de mantener pero que tarda demasiado para consultar datos puede llegar a ser algo muy malo.</p>
<p>Como conclusión yo diría que si requieres una aplicación donde el rendimiento sea el factor mas importante utilices JDBC, pero por otra parte si el rendimiento es algo que no están importante puedes utilizar JPA o Hibernate.</p>
<h2></h2>
<h2>Tutorial de JPA Gratis!!</h2>
<p>Si estás leyendo esto en este momento es por seguramente estas interesado en aprender Hibernate o JPA, pues te tengo buenas noticias, ya que he iniciado un tutorial muy completo de JPA para que aprendas desde cero y sin conocimientos previos como utilizar JPA. No te sientas mal si lo que tu buscas es aprender Hibernate, ya que actualmente existe una implementación de JPA desarrollada por Hibernate. Además, JPA es el ORM Estándar de Java y que se integra a la perfección con el resto de especificaciones de Java, como lo es EJB 3.X, CDI, Bean Validator, entre otras más. Pues bien, si estas interesado en tomar este tutorial puedes <a href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">entrar aquí</a>.</p>
<p>&nbsp;		</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2014/07/15/jpa-hibernate-vs-jdbc/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">24</post-id>	</item>
	</channel>
</rss>
