Configuración por anotaciones

Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.

Crearemos un proyecto con Maven siguiendo, utilizando este pom.xml.

Creamos el fichero hibernate.cfg.xml en la carpeta src/main/resources y le pegamos el siguiente código:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.isolation">2</property>
<property name="hibernate.connection.password">pp</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/prueba?serverTimezone=UTC</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.current_session_context_class">managed</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>

DDL automático

  • update → cada vez que arranquemos el servidor, se comprobará si hay cambios en las entidades de hibernate y si es así, se actualizará la base de datos en función de dichos cambios (en caso de que sea posible)
  • create_drop → cada vez que arranquemos el servidor se creará la base datos y se borrará al detenerlo
  • create → recrea la base de datos al arrancar, borrando lo que había
  • validate → comprueba que lo que tengo en la aplicación corresponde a lo que hay en la base de datos y si no es así, lanza un error

Si no pones el property, no se ejecuta ninguna acción.

hibernate.cfg.xml:
<property name="hbm2ddl.auto">create</property>

Creamos el fichero HibernateUtil.java para establecer la conexión

public class HibernateUtil {
	private static StandardServiceRegistry registry;
	private static SessionFactory sessionFactory;

	public static SessionFactory getSessionFactory() {
		if (sessionFactory == null) {
			try {
				registry = new StandardServiceRegistryBuilder().configure().build();
				MetadataSources sources = new MetadataSources(registry);
				sources.addAnnotatedClass(Libro.class);
				sources.addAnnotatedClass(Autor.class);
				Metadata metadata = sources.getMetadataBuilder().build();
				sessionFactory = metadata.getSessionFactoryBuilder().build();
			} catch (Exception e) {
				e.printStackTrace();
				if (registry != null) {
					StandardServiceRegistryBuilder.destroy(registry);
				}
			}
		}
		return sessionFactory;
	}
}

Las entities

@Entity
// Anotación opcional, permite especificar el nombre de la tabla vinculada a esta entidad en la base de datos
// @Table(name = "autorcillo")  
public class Autor {
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)//Para generar números autoincrementados
	private int id;
	
	//Anotación opcional, permite easpecificar el nombre d ela tabla en la base de datos, los caracteres que tendrá y si acepta valores nulos
	//@Column (name = "nombrecillo", length = 100, nullable = true)
	private String nombre;
	
	// mappedBy especifica el atributo de la entidad vinculada con el que estamos estableciendo esta relacion.
	//Si no lo ponemos se gererará una tabla auxiliar.
	// CascadeType.ALL: Los datos se borrarán y se salvarán en cascada
	// orphanRemoval: si borro en cascada y queda algún registro hijo sin padre, cárgatelos también
	// eager = carga ansiosa 
	@OneToMany (mappedBy = "autor", cascade = {CascadeType.ALL}, orphanRemoval = true, fetch = FetchType.EAGER) 
	private List<Libro> libros;

	// Los getters y setters
}
@Entity
public class Libro {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) // Para generar números autoincrementados
	private int id;
	private String titulo;
	private int precio;
	@ManyToOne
	// Anotación opcional, permite especificar el nombre de la join column
	// @JoinColumn (name = "autor_id")
	private Autor autor;

	// ... los getters y setters
}

Generación de getters y setters con Lombok

Podemos getionar la generación automática de getters y setters en nuestras entidades utilizando las anotaciones de Lombok.

Pasos en su implementación.

1. Debemos tener incluída la dependencia correspondiente en nuestro pom.xml.

2. Añadimos las siguientes anotaciones a la entidad. Esto genera automáticamente getters y setters para todas las propiedades.

@Getter @Setter
@Entity
public class Libro {

3. Ejecutamos el jar correspondiente a lombok que se habrá instalado a través de maven.

Configuración por anotaciones 1

4. En un momento de instalación se nos pregunta por la ubicación de nuestra instalación de Eclipse. Si la herramienta no lo detectase, deberemos especificar la ubicación manualmente.

5. A partir de ahora, podremos usar las anotaciones @Getter y @Setter para generar los getters y setters.

Probando la configuración con una transacción

Conjunto de operaciones contra la base de datos que se realizan de forma atómica (o todas o ninguna).

¿Cuando nos interesa crear una transacción? Cuando modificamos la base de datos (y por tanto deseamos poder hacer rollback()). Para una consulta no es necesario. Crear una transacción consume recursos.

  • Un objeto Session Hibernate representa una única unidad-de-trabajo y es abierta por un ejemplar de SessionFactorySe deben cerrar las sesiones cuando se haya completado todo el trabajo de una transación.
  • En caso de fallo, lo que hay dentro del beginTransaction y el commit no se ejecuta y se salta a un catch.
  • Siempre es más rápido hacer dos operaciones en una sola transacción que dos operaciones en dos transacciones.
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
Autor a = new Autor();
a.setNombre("Juan");
		
session.save(a);
transaction.commit();
session.close();

setTimeout()

sesion.beginTransaction().setTimeout(400);
  • Si pasados 400 milisegundos la base de datos no devuelve nada, se arrojará una UnCaught Eception (una excepción para la que no es estrictamente neceario tener un try catch; al contrario que las Caught Exception).
  • Este timeout se puede gestionar a nivel de aplicación o a nivel de base de datos.
← Instalación (pasos comunes para configuración por anotaciones y XML)
Métodos de la clase Session →