Hibernate provee 3 estrategias para resolver el mapeo de herencias.
La primera es utilizar una sola tabla lo que es recomendable cuando los objetos “hijos” o subclases no agregan gran cantidad de propiedades.
La segunda es utilizar una tabla para la clase “Padre” y los atributos de las subclases en otras tablas.
La tercera es utilizar una tabla por clase.
Si utilizamos una sola tabla deberíamos utilizar una columna que indique de que tipo es el registro que se esta guardando. Este registro se llama discriminator . Por ejemplo en el mapeo de nuestra clase padre deberíamos agregar la siguiente entrada para indicar el dicriminador:
Y además debemos indicar la subclase:
.....
Con anotaciones podemos hacerlo como muestra el ejemplo:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name="planetype",
discriminatorType=DiscriminatorType.STRING
)
@DiscriminatorValue("Plane")
public class Plane { ... }
@Entity
@DiscriminatorValue("A320")
public class A320 extends Plane { ... }
Si utilizamos una tabla con los datos genéricos y otras por subclase se debe mapear de la siguiente manera:
.....
El atributo key indica cual es el nombre de la columna que contiene el id de la clase padre. Veamos un ejemplo:
...
Si utilizamos una tabla por clase se debe declarar de la siguiente manera:
.....
En este caso no es necesario un discriminador ya que cada tabla tiene su clase.
Es
una noticia que se venia venir; oracle anuncio que va a cambiar el
modo en que hace dinero con mysql . Ahora va a tener un “core”
libre y productos comerciales ni libres, ni gratuitos. Imagino que
muchas empresas que optaron por el software libre van a pasarse a
otros proyectos. Me
imagino que esto impulsara el proyecto MariaDB en el que esta
trabajando Monty el creador de MySQL. Creo que también le dará un
empujón a PostgreSQL que viene creciendo de una forma constante. No
estoy en desacuerdo que una empresa haga dinero, es su objetivo pero
creo que por nada del mundo puede cambiar el modelo de negocio de uno
de sus productos. No solo porque pierde credibilidad sino que porque
tambien esta traicionando a sus clientes. Que
opinan de esta noticia?
Bueno ahora viene mi opinión, creo que nuestra profesión es fantástica, si te gusta estudiar todo el tiempo, evolucionar, actualizar constantemente.
El conjunto de incumbencias de nuestra profesión nos posibilitan a dirigir proyectos como a programar y aquí el problema porque el programar nos deja en competencia con el programador de la esquina que sin desmerecer a los programadores de raza (o que aprendieron "de la vida") cobra mucha veces más barato o se olvida de la calidad en pos de un buen precio.
Creo que el mercado es amplio hoy en día todos tenemos oportunidad es necesario saber "venderse" para dejar sentado nuestra calidad. Calidad que se ve reflejada por el precio, los tiempos y el código. Estoy convencido que este es el camino para crecer como profesión.
Hibernate nos permite definir las relaciones de nuestros objetos con las tablas de la base de datos por medio de un archivo xml y por medio de anotaciones en la clase.
Veamos con mayor detalle las partes de este mapeo.
Primero se define la clase y la tabla:
< class name="event" table="events">
...
Cuando usamos anotaciones llamamos a @Entity que indica que la clase es una entidad manejada por hibernate y se va a persistir. Además con @Table indicamos el nombre de la tabla.
Luego se puede definir el id, de la siguiente forma:
name: Indica el nombre de la propiedad.
type: indica el tipo.
column: la columna en la base de datos.
unsaved-value: Valor que toma cuando el objeto no esta guardado.
access: como va aceder hibernate a esta propiedad.
Esto es similar a utilizar la anotación @Id en Jpa.
El generator es el motor que indica como hibernate se va a manegar para obtener los números de las claves nuevas.
Hibernate ofrece varias estrategias:
IDENTITY: soporta id autoincrementales en DB2, MySQL, MS SQL Server, Sybase and
HypersonicSQL .
SEQUENCE : Usa secuencias de la base.
TABLE: Toma el nombre de la tabla y la columna como fuente y genera una un identificador a partir de estas.
AUTO: Toma el más conveniente según el motor de base de datos.
Cuando son claves compuestas las cuales se encuentran en una clase embebida se puede definir de la siguiente manera:
......
Cuando tenemos claves compuestas que no se encuentren en una clase envevida podremos definirla de la siguiente manera:
Version
Cuando queremos que hibernate detecte los conflictos podemos agregar un campo versión, que indica la versión del registro. De esta forma hibernate incrementara este registro cada vez que guarde.
También se puede utilizar un timestamp para mantener la versión de los registros.
Con anotaciones podemos usar el @Version.
Property
Con Property declaramos una propiedad de nuestro objeto:
Componentes o objetos embebidos
Se pueden definir estructuras de objetos contenidos en el archivo contenedor, de esta forma nos ahorramos hacer un archivo de mapeo. Cuando la clase contenida es utilizada en 2 o más clases no es conveniente utilizar componentes.
Es una visión de las empresas de software, habría que hacer un articulo pero desde la visión de los programadores.
En mi opinión creo que unas de las razones del recambio es que las empresas de software no comparten sus ganancias. Todo es dinero y me parece genial que empresas ganen bien; pero esas ganancias se deben reflejar también en el sueldo de sus empleados.
Hacer mvn clean install y mvn eclipse:eclipse. Refrescar el proyecto en eclipse para que tome los cambios.
Generar clase y su mapeo:
Creeamos una clase persona:
package com.ejemplo;
/**
* @author emanuel
*
*/
public class Persona {
private Long id;
private String nombre;
private String apellido;
public Persona(String nombre, String apellido) {
super();
this.nombre = nombre;
this.apellido = apellido;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getApellido() {
return apellido;
}
public void setApellido(String apellido) {
this.apellido = apellido;
}
//Constructor usado por hibernate
protected Persona() { }
}
Ahora creamos el archivo de mapeo, el cual es un archivo .xml el cual es deseable (no obligatorio) que se llame igual que la clase que mapea y se encuentre en la carpeta resources con la estructura de paquete que tiene la clase, por lo tanto el path sería:
main/resources/com/ejemplo/persona.hbm.xml y el archivo sería como el siguiente:
Configurar hibernate:
Para configurar hibernate es necesario generar un archivo hibernate.cfg.xml y guardarlo en la carpeta resources. Este archivo contendra la siguiente información:
Ahora vamos a crear una clase util, la cual sera encargada de generar las sessiones de Hibernate:
package com.ejemplo.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
Crear un test:
Vamos a generar un test para probar como todo funciona:
package com.ejemplo;
import static org.junit.Assert.*;
import java.util.List;
import org.hibernate.classic.Session;
import org.junit.Test;
import com.ejemplo.util.HibernateUtil;
public class HibernateTest {
@Test
public void test() {
Persona persona = new Persona("Juan","Rodriguez");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(persona);
session.flush();
List personas = session.createQuery("from Persona").list();
assertFalse(personas.isEmpty());
Persona personaGuarda = (Persona) session.get(Persona.class, persona.getId());
assertEquals(persona, personaGuarda);
}
}
Crear esquema en la base de datos:
Es necesario escribir un esquema llamado prueba en la base de datos Mysql.
Google planea matar a javascript con un dardo. Google Dart es el nuevo lenguale de google que pretende suplantar a javascript. Dart se ha descrito como “un nuevo lenguaje de programación orientado hacia la programación web estructurada”. También hay rumores que va a ser un lenguaje orientado a objetos similar a SmallTalk. Me imagino que google quiere revertir la historia que tuvo con Go su lenguaje de programación, el cual no fue muy exitoso por su parecido con C y también tenia una mezcla con python.
Este lenguaje va a ser presentado en el GoTo que se celebra en Dinamarca en el mes de octubre. Los responsables del lenguaje son Lars Bak y Gilad Bracha, dos ingenieros de software de Google con experiencia en diseño de lenguajes.
Bracha es el creador del lenguaje de programación Newspeak y antes de estar en Google fue vicepresidente en SAP Labs, además de reputado ingeniero en Sun Microsystems; entre otras cosas es co-autor de Java Language Specification e investigador en el área de lenguajes de programación orientado a objetos.
En cuanto a Lars Bak, es conocido como un veterano de las máquinas virtuales. Diseñó e implementó máquinas virtuales orientadas a objetivos y trabajó en proyectos como Beta, Self, Strongtalk, Sun HotSpot, OOVM Smalltalk y el motor V8 de Google para el navegador Chrome.
Éste sábado 17 de setiembre de 2011 se estará realizando el Software Freedom Day, o Día de la Libertad del Software. Es una celebración anual a nivel mundial que se realiza desde hace 7 años para celebrar las virtudes del software libre y los beneficios de compartir.
Software Freedom Day es una celebración global del Software Libre y abierto (FLOSS).
En nuestros días donde nuestras vidas son cada vez más dependientes de la tecnología, es importante que tomemos el tiempo de considerar el impacto tecnológico que este tiene y la importancia de asegurarnos que la tecnología no esta siendo usada para limitarnos, pero para tomarnos más lejos en ruta de oportunidad, innovación y libertad para todas las personas.
Dejo links:
CoffeeScript es un lenguaje que “compila” dentro de javascript dando mayor facilidad a la hora de escribir código. Es un lenguaje dentro de javascript para hacernos las cosas más fáciles. Personalmente creo que javascript no es muy natural pero es un gran lenguaje. El principal problema al escribir código es nuestro desconocimiento sobre el lenguaje, nadie estudia a fondo como funciona javascript.
Después de la reflexión dominical veamos unos ejemplos como nos puede ayudar coffeeScript a escribir código:
En javascript es así
var fill;
fill = function(container, liquid) {
if (liquid == null) liquid = "coffee";
return "Filling the " + container + " with " + liquid + "...";
};
En coffeescript así:
fill = (container, liquid = "coffee") ->
"Filling the #{container} with #{liquid}..."
Además de todas estas ventajas permite escribir clases:
class Animal
constructor: (@name) ->
move: (meters) ->
alert @name + " moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
class Horse extends Animal
move: ->
alert "Galloping..."
super 45
sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"
sam.move()
tom.move()
Por fin se decidió la sintaxis del operador lambda en java 8. Luego de muchas discusiones se decidió por la sintaxis de scala que es igual a la que usa C#. Me parece muy bien, se habían disparados supuestos y ejemplo de otras sintaxis que para mi gusto no eran cómodas ni elegante.
Sin más veamos unos ejemplos:
x => x + 1
(x) => x + 1
(int x) => x + 1
(int x, int y) => x + y
(x, y) => x + y
(x, y) => { System.out.printf("%d + %d = %d%n", x, y, x+y); }
() => { System.out.println("Hola!"); }
El objetivo de una prueba unitaria es probar un solo objeto, pero en ciertas ocasiones las colaboraciones entre objetos tienen un acoplamiento alto por lo tanto no puedo probar un objeto sin llamar a otro. Es aquí donde los test se ensucian un poco, en especial si el objeto que deseamos testear depende de algún objeto “pesado” o que tenga interacción con algún otro sistema externo, servidor o base de datos. Por ejemplo testear un objeto que valide el nombre de usuario y la clave en un ldap.
Una estrategia de solución para este problema es usar objetos mocks, los objetos mocks son objetos “de mentira” que permiten simular otro objeto o entidad del sistema. Si vamos a la wikipedia podremos encontrar la siguiente definición:
En la programación orientada a objetos se llaman objetos simulados (pseudoobjetos, mock object, objetos de pega) a los objetos que imitan el comportamiento de objetos reales de una forma controlada. Se usan para probar a otros objetos en pruebas de unidad que esperan mensajes de una clase en particular para sus métodos, al igual que los diseñadores de autos usan un crash dummy cuando simulan un accidente.
En los test de unidad, los objetos simulados se usan para simular el comportamiento de objetos complejos cuando es imposible o impracticable usar al objeto real en la prueba. De paso resuelve el problema del caso de objetos interdependientes, que para probar el primero debe ser usado un objeto no probado aún, lo que invalida la prueba: los objetos simulados son muy simples de construir y devuelven un resultado determinado y de implementación directa, independientemente de los complejos procesos o interacciones que el objeto real pueda tener.
Existen diferentes frameworks en java para hacer mocks, easymock, mockito, etc. Vamos a utilizar mockito.
Mockito es un framework simple, fácil de usar para hacer objetos mocks en java. Tiene una interfaz simple y natural.
Características:
Se pueden crear mocks de interfaces y clases concretas.
Verificación de invocaciones (cantidad exacta, al menos una vez, órden de invocación, etc.)
El stack trace se mantiene limpio, ya que los errores ocurren en los assert que se hagan (y no dentro del método bajo prueba).
Un API más clara para crear stubs y verificaciones.
Vamos a hacer un objeto mock con mockito:
//creamos el mock y el stub
ArrayList instance = mock(ArrayList.class);
doReturn("hola mundo").when(instance).get(0);
//ejecutamos la lógica a probar
instance.get(0);
//verificamos que se hayan invocado los métodos
verify(instance).get(0)
Como se puede ver la api es clara y simula el lenguaje natural. En la primera linea creamos un objeto mock de la lista; luego indicamos que cuando se llame el método get con el parámetro 0 debe devolver “hola mundo”. Luego ejecutamos el método y luego se verifica si este método se corrió.
Para agregar este framework a nuestro proyecto maven es solo necesario agregar esta entrada en el pom:
Junit 4 es un framework de test unitario basado en anotaciones. Nos permite realizar el mismo trabajo que JUnit 3 pero con anotaciones, proveyendo mayor flexibilidad y simplicidad a nuestro código.
JUnit provee elementos que nos facilitan probar entidades o clases de nuestro programa:
Permite cargar los test de forma transparente
Provee anotaciones que facilitan el testing: @Before, @BeforeClass, @After, and @AfterClass
Provee diferentes asserts
Integración con IDEs (eclipse, netbeans) y herramientas como maven y ant.
Veamos un ejemplo de test con JUnit:
import static org.junit.Assert.*;
import org.junit.Test;
public class CalculatorTest {
@Test
public void testAdd() {
Calculator calculator = new Calculator();
double result = calculator.add(10, 50);
assertEquals(60, result, 0);
}
}
En la primera linea se importan los métodos de la clase estática Assert, la cual cuenta con sin fin de asserts, que facilitan nuestros test.
Con @Test indicamos que ese método es un Test. Además con el método assertEquals de la clase Assert verificamos si el resultado es igual a 60.
Test Case son casos de prueba, en JUnit 4 son los metodos que estan anotados con @Test
Test Suite son un conjunto de Test Case, JUnit 4 genera automáticamente un Test Suite cuando se corren todos los test de una clase.
Veamos un ejemplo de Test Suite:
@RunWith(value=org.junit.runners.Suite.class)
@SuiteClasses(value={FolderConfigurationTest.class,
FileConfigurationTest.class})
public class FileSystemConfigurationTestSuite {
}
Con @RunWith configuramos el Runner para correr los Test Suite. Runner es el motor que corre los test, JUnit proporciona uno por defecto que por medio de anotaciones se puede cambiar. Y con la anotación @SuiteClasses indicamos que clases correr.
Existen diferentes frameworks para ayudarnos a realizar pruebas unitarias, como por ejemplo PHPUnit para PHP, NUnit para .net y JUnit para Java. En java JUnit es el framework más utilizado para hacer pruebas unitarias, pero no el único; existen otros como TestNG, JTiger.
TestNG y JTiger estan basados en anotaciones y nacieron principalmente para suplir algunas deficiencias que tenia JUnit 3.
JUnit es una herramienta simple, Open Source que se ha convertido en el estándar para probar clases java de forma unitaria.
Fue creada por Erich Gamma y Kent Beck.
Es fácil de usar y configurar por lo que prácticamente no existe curva de aprendizaje, salvo el cambio de mentalidad que debe producir en las mentes de los programadores al usar técnicas que faciliten el uso de pruebas unitarias.
El propio framework incluye formas de ver los resultados (runners) que pueden ser en modo texto, gráfico (AWT o Swing) o como tarea en Ant.
En la actualidad las herramientas de desarrollo como Netbeans y Eclipse cuentan con plug-ins que permiten que la generación de las plantillas necesarias para la creación de las pruebas de una clase Java se realice de manera automática, facilitando al programador enfocarse en la prueba y el resultado esperado, y dejando a la herramienta la creación de las clases que permiten coordinar las pruebas.
Desde la versón 4 de JUnit hubo grandes cambios, con respecto a otras versiones dado que la versión 4 de JUnit esta orientada a anotaciones dando mayor potencial al framework y flexibilidad.