SlideShare una empresa de Scribd logo
Hibernate / JPA @luce5
Embedded
Embedded
•
•
•

Clases que no tienen relación directa con una tabla (están contenidas dentro
de otra tabla)
o Ejemplo clásico: Usuario y dirección.
Para mapear, @Embeddable para indicar que una clase se puede incluir
dentro de otra y @Embedded para incluir dentro de una clase.
Añadid dirección a las solicitudes
o @Embeddable a la clase dirección (en vez de @Entity)
o y @Embedded en el atributo dirección dentro de solicitud.
Modos de identidad
Modos de identidad
•

•

Identidad de Tabla:
o @Id
o Compuesto:
 Varios @Id
 @EmbeddedId (clase con @Embeddable y referencia con
@EmbeddedId)
 Id en otra clase y @IdClass en la tabla
Probad cualquiera de estas referencias.
Modos de identidad
•
•

Por favor, usad una clave subrogada.
Las claves compuestas sólo dan problemas
o Pueden no ser inmutables
o Los requisitos cambian y afectan a las claves
o Son menos eficientes (ocupan más)
o Son menos uniformes
o Son incómodas en Java (varios setters)
o Son peores en Hibernate
Modos de identidad
•

•
•

Generación:
o Identidad (DB2, MySQL, SQL Server...)
o Secuencia
o Tabla (hi/lo a una tabla)
o Auto
o 14 algoritmos más
En base a @GeneratedValue y seleccionando la estrategia y el generador
(@SequenceGenerator, entre otros).
Probad @SequenceGenerator para ver las opciones de configuración.
Modos de identidad
•

Además de un @Id puedes definir que una columna es un Id Natural:
o … @NaturalId
o buscar por natural id bySimpleNaturalId
Modos de identidad
•
•
•

¿Qué es la identidad?
o Identidad de la BD
o Identidad de Java
Para una MISMA sesión, las dos cosas son lo mismo.
Y fuera? Hibernate no garantiza igualdad.
Modos de identidad
•
•

Esto es importante en un par de casos sólo:
o Composite Primary Key Class
o 2 instancias de la misma clase en un Set en sesiones diferentes
Implementa equals y hashCode, teniendo en cuenta que dos objetos
diferentes pueden representar el mismo objeto en la base de datos.
Modos de identidad
•
•

•

Repetimos...
o Si usas primary keys compuestas
o O si quieres unir entidades detached (luego veremos que es...) que reúsas
en un Set
Deberías implementar equals y hashCode:
o Comparando por igualdad de negocio (columnas y valores que identifican
univocamente a una entidad)
https://community.jboss.org/wiki/EqualsAndHashCode
Modos de locking
Modos de locking
•
•
•
•

Hasta ahora, sin saberlo, estamos trabajando con un modo last commit wins.
Cuando vamos a trabajar con algo, Hibernate recupera la entidad de la base
de datos. Si cuando guardamos los datos han cambiado, ese usuario pierde
esa información.
Podemos trabajar de forma optimista, al guardar Hibernate comprueba que
no se han tocado las cosas.
Si se han tocado da un error, si no, sigue con su trabajo.
Modos de locking
•

Para activarlo, sólo tenemos que definir un atributo de tipo Integer anotado
con @Version.
o Podemos usar un Date también

•

Probadlo!

•
•

En cualquier momento podemos llamar a un lock pesimista con session.lock()
[Avanzado] Si tenéis tiempo... bloquead la inserción de una tabla.
Herencia
Herencia
•

•
•

Estrategias
o Tabla por clase concreta
 Con polimorfismo implícito
 Con uniones
o Tabla por jerarquía de clases
o Tabla por subclase
o Relaciones polimórficas
+ combinaciones de las anteriores
JPA no soporta todo lo que soporta Hibernate
Tabla por clase concreta con
polimorfismo implícito
Tabla por clase concreta con
polimorfismo implícito
•
•

Es simple, consultar contra clases concretas
Contrapartidas…
o Polimorfismo
 Requiere una consulta por cada subclase concreta
 Las asociaciones no se representan bien (no aceptan una FK simple)
o Semánticas compartidas entre tablas
o El esquema relacional no “conoce” la relación
o No se puede hacer una asociación hacia la abstracta (ya que no es una
entidad)
Tabla por clase concreta con
polimorfismo implícito
@MappedSuperclass
public abstract class AbstractPago
@Entity
public class PagoPAC extends AbstractPago
@Entity
public class PagoBeca extends AbstractPago
Tabla por clase concreta con uniones
Tabla por clase concreta con uniones
•

Permite relaciones hacia la clase abstracta

•

Consultas optimizables por el SGBD

•

Contrapartidas…
o El esquema relacional no “conoce” la relación
Tabla por clase concreta con uniones
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractPago
@Entity
public class PagoPAC extends AbstractPago
@Entity
public class PagoBeca extends AbstractPago
Tabla por jerarquía
Tabla por jerarquía
•

La mejor para el polimorfismo y para no polimorfismo

•

Contrapartidas…

o Requiere columnas nullables en las subclases
o Posible desperdicio de espacio
o Requiere discriminador
Tabla por jerarquía
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="tipo",
discriminatorType=DiscriminatorType.STRING)
public abstract class AbstractPago

@Entity
@DiscriminatorValue("PAC")
public class PagoPAC extends AbstractPago
@Entity
@DiscriminatorValue("beca")
public class PagoBeca extends AbstractPago
Tabla por subclase
Tabla por subclase
•

Basada en FKs

•

Esquema normalizado

•

Contrapartidas…
o Complica el esquema
o Ineficiente en jerarquías complejas*
o Clase padre concreta
Tabla por subclase
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractPago
@Entity
public class PagoPAC extends AbstractPago
@Entity
public class PagoBeca extends AbstractPago
Limitaciones de herencia
•
•

Limitaciones oficiales
Implementad alguna!
o session.createCriteria(Petition.class) .list();
Relaciones polimórficas
•
•
•

Permite mapear relaciones que no se podrían de otra forma: asociaciones
polimórficas a clases desde múltiples tablas
Sólo para situaciones muy especiales
Contrapartidas…
o No puede establecer FKs
o Envers no lo soporta ☹
Relaciones polimórficas
public interface Cosa
@Entity
public class Beca implements Cosa

@Entity
public class Pago implements Cosa
@Any(metaColumn = @Column(name = "tipo_de_cosa"))
@AnyMetaDef(idType = "long", metaType = "string", metaValues = {
@MetaValue(value = "Beca", targetEntity = Beca.class),
@MetaValue(value = "Pago", targetEntity = Pago.class) })
@JoinColumn(name = "tipo_de_cosa_id")
public Cosa getCosa() {
Mapeos 'complejos'
Mapeos 'complejos'
•

@SecondaryTables + @SecondaryTable + @PrimaryKeyJoinColumn

•

@Parent

•

@Target

•

@NotFound
Batch Processing
Batch Processing
•

¿Qué pasa si lanzamos esto?

Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Petition petition = new Petition(.....);
session.save(petition);
}
tx.commit();
session.close();
Batch Processing
•
•

Hibernate se queda sin memoria.
Podemos arreglarlo, haciendo operaciones en batch:
o Activando hibernate.jdbc.batch_size (en persistence/hibernate.cfg.xml) y
poniendolo a un valor entre 10-50
Batch Processing
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Petition petition = new Petition(.....);
session.save(petition);
if ( i % 20 == 0 ) { //el valor de la propiedad
session.flush();
session.clear();
}
}
tx.commit();
session.close();
Batch Processing
•

•
•

Stateless Session
o Sin caché de primer nivel
o Sin caché de segundo nivel
o Sin dirty checking/write behind
o Sin cascades
o Sin interceptores
o Similar a JDBC
Scrollable
HQL
Batch Processing
•
•

En estrategias de Fetch hay una adicional (cuarta)
o @BatchSize, recupera sentencias en bloque.
MUY interesante...
o soluciona el problema de los N+1 fetches.
Servicios
Servicios
•

Un sistema de extensión (similar a plugins) de Hibernate.
o Desde Hibernate 4.0
o Permite el registro de servicios/implementaciones alternativas para, por
ejemplo:
 TransactionFactory (transacciones)
 JtaPlatform (gestión de JTA)
 JndiService
 JdbcServices
 ConfigurationService
 ...
Transitividad (cascades)
Transitividad
•

Cascades de JPA:
o CascadeType.PERSIST: cascada de persists
o CascadeType.MERGE: cascadas de merges
o CascadeType.REMOVE: cascade de eliminaciones
o CascadeType.REFRESH: cascade de refresh (volver a leer una entidad de
BD)
o CascadeType.DETACH: cascade de detach (desunir de sesión)
o CascadeType.ALL: todos los de arriba
Transitividad
•

Cascades de Hibernate (@Cascade):
o save-update...
o delete
o lock
o replicate (copiar un objeto, muy muy raro)
o evict
o delete-orphan
Transitividad
•

•

Delete orphan es interesante:
o Sólo aplica a oneToMany.
o Cuando elimino un elemento hijo de la colección indico que quiero
eliminarlo de la BD porque se ha quedado huérfano.
o orphanRemoval en @OneToMany.
 No estoy haciendo esto: session.remove()
 padre.geHijos().remove(0)
o No cuenta para Cascade.ALL.
o @OneToMany(orphanRemoval = true)
Probadlo!
Transitividad
•

Recomendaciones de cascade:
o Es más lógico en relaciones @OneToOne y @OneToMany (padre con
hijos)
o Si el objeto hijo en un @OneToMany no tiene sentido sin el padre ->
Cascade.ALL y orphanRemoval
o Típicos: persist, save-update...
Caching
Caching
•
•
•

Caché de primer nivel
o get() y load() me recuperan objetos que tienen en la sesión...
Caché de segundo nivel
Caché de queries
o Hibernate tiene en cuenta cambios en los objetos que se muestran en las
consultas.
o Depende del patrón de uso de la aplicación.
Caching
•

Caché de segundo nivel:
o Muy común, Hibernate se integra muy bien con varios proveedores de
caché.
o Típico para tablas de referencia (provincia, localidad, datos maestros...)
o Marcar entidades interesadas (o colecciones): @Cacheable

o @Cache(usage = CacheConcurrencyStrategy.TIPO_DE_CACHING)
Caching
•

Tipos de Caching:
o NONE
o READ_ONLY: no se modifican a menudo...
o NONSTRICT_READ_WRITE: pocas transacciones apuntando al mismo
item...
o READ_WRITE: actualizaciones frecuentes.
o TRANSACTIONAL
Caching
•

Típicos proveedores:
o EHCache: soporta todos los tipos de caching
o Infinispan: read-only, transactional
Caching
•

Queries:
o Activar use_query_cache
o Establecer el tiempo de timeout
o Establecer las queries que quieres cachear
 setCacheable(true)
Performance
Performance
•
•

Hibernate no es lento.
Recomendaciones de rendimiento:
o Tener en cuenta las 4 estrategias de fetching (Select, Subselect, Join,
BatchSize)
o Cuidado con N+1
o Fetch-profiles (para personalizar escenarios de búsqueda)
o Personalizar Fetch en Criterias
(criteria.setFetchMode("propiedad",MODO)) EAGER=JOIN, LAZY=SELECT
 Probadlo!"
Performance
•
•
•

Tres grandes tipos de colecciones:
o indexed collections (mapas, listas, arrays)
o sets
o bags
Las dos primeras son las más eficientes en save/remove/update de
elementos.
Bags y lists son más eficientes en @OneToMany con mappedBy
Performance
•

•

One-shot-delete
o Imaginemos que tenemos 20 elementos, eliminamos 18 y añadimos 3
o Podemos borrar 18 elementos (1 a 1) e insertar 3
o Eliminar todo e insertar 5
 En este caso conviene hacer clear();
Probadlo!
Performance
•
•

Marcar claves naturales @NaturalId (puede mejorar rendimiento al acceder a
ellas)
Realizar mapeos sencillos (los que hemos visto)
Performance
•

Si realiza muchas consultas:
o plantear estrategias estilo JOIN/SUBSELECT
o Activar batch o utilizar @BatchSize
o Activar caché de segundo nivel
o HQL
o SQL
o Query cache
Performance
•

Si realiza una consulta muy pesada:
o Eliminar cruces JOIN (empezando por colecciones)
o Poner asociaciones *ToOne a Lazy (con Select o Subselect)
o Índices
o HQL
o SQL
o Query cache
Validaciones
Validaciones
•
•

Hibernate se complementa con Hibernate Validator
Es la base de Bean Validation, un estándar Java EE 6
o @NotNull
o @Past
o @Size
o @Pattern
o @Max
o @Email
o @CreditCardNumber
Validaciones
•
•

Incluid las librerías de validation (es más sencillo en Java EE)
o Añadid una anotación y probad a guardar.
Podemos llamar a los validadores con:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<User>> constraintViolations =
validator.validate(user);

•

Probadlo!
Envers
Envers
•
•
•

Librería de auditoría.
Para activar la versión "básica" basta con:
o Copiar la librería
o @Audited
o Cuidado con relaciones: @NotAudited (de momento)
Probadlo!
Envers
•

Puedo hacer queries específicas:

AuditQuery query = AuditReaderFactory.get(session)
.createQuery()
.forEntitiesAtRevision(MyEntity.class, revisionNumber);
query.uni../getResu..()

•

Probadlo!
Envers
•

Dos estrategias, start y start-end

•

Puedo guardar el usuario o información adicional

•

Las querys pueden llegar a ser complejas:

List personsAtAddress = getAuditReader().createQuery()
.forEntitiesAtRevision(Person.class, 12)
.addOrder(AuditEntity.property("surname").desc())
.add(AuditEntity.relatedId("address").eq(addressId))
.setFirstResult(4)
.setMaxResults(2)
.getResultList();
Envers
•

Puedo preguntar a una entidad por las revisiones que ha tenido

Number revision = (Number) getAuditReader().createQuery()
.forRevisionsOfEntity(MyEntity.class, false, true)
.setProjection(AuditEntity.revisionNumber().min())
.add(AuditEntity.id().eq(entityId))
.add(AuditEntity.revisionNumber().gt(42))
.getSingleResult();

•

Probadlo!
Envers
•

•

Envers es más quisquilloso en algún tipo concreto de mapeos:
o Bags
o @OneToMany+@JoinColumn, mappedBy (necesita @AuditJoinTable)
o @OneToMany+@JoinColumn, insertable=false, updatable = false
(necesita @AuditMappedBy)
Siempre se puede decidir no auditar una relación con @NotAudited.
Multi-tenancy
Multi-tenancy
•

Una aplicación que sirve múltiples clientes.

•

Típico de SaaS (Software as Service: google docs)

•

Cada cliente sólo debe poder ver sus datos
o Base de datos diferente, JDBC que cambia
o Esquema separado, schema que cambia al conectarse
o Única base de datos, discriminador
Multi-tenancy
•
•

En Hibernate:

Session session = sessionFactory.withOptions()
.tenantIdentifier( yourTenantIdentifier )
.openSession();

Opciones de identificador:
o DATABASE
o SCHEMA
o DISCRIMINATOR (No soportada aún, Hibernate 5)
¿Qué más es
Hibernate?
¿ Qué más es Hibernate?
¿Qué más es Hibernate?
•
•
•
•
•
•
•
•
•
•

Core
Shards: fragmentación horizontal
Search: búsqueda de texto completo (Lucene)
Tools
Validator: validación de datos
Metamodel Generator
OGM
Annotations
Entity Manager: operaciones y ciclo JPA
Envers: versionado e histórico
Recomendaciones y
errores habituales
Recomendaciones
•
•

No utilices claves compuestas
o Claves surrogadas siempre, ni naturales ni compuestas
En el import.sql (ficheros sql que carga Hibernate directamente), los ids,
negativos (para no hacer conflicto con ids generados)

•

No uses herencia, usa agregación (GoF)

•

No uses mapas, usa entidades y relaciones
Recomendaciones
•
•
•
•

Cuando estés mapeando por primera vez, hacer tests (incluso vacíos) está
bien:
o No arrancas el servidor de aplicaciones!
Ojo con los "lazos" en los modelos y las relaciones bidireccionales...
Se puede implementar SoftDelete (@SQLDelete) o restricciones globales de
búsqueda (@Where)
Puedo ver los valores de las consultas (?) -> en log4j, org.hibernate.type a
TRACE.
Errores típicos
•

Lazy Initialization Exception, causado por:
o Intentar cargar desde la vista/lógica con la sesión cerrada una lista de
objetos/objeto con fetch a LAZY.
o -> Hibernate.initialize()
o -> Activar lazy load sin transacciones:
hibernate.enable_lazy_load_no_trans
o -> OpenSessionInView
o -> Conversaciones
Errores típicos
•

•

Detached entity passed to persist, causado por:
o Fijar un id manualmente a una entidad que utiliza un auto-generado
o Sin cascadas, intentar guardar una relación de un objeto que no está en la
base de datos.
o Llamada persist() o save() de un objeto que ya está en la BD
Cannot Open Connection, causado por:
o Malos valores de conexión a la BD.
Errores típicos
•
•
•

NPE en IntegerType.next(IntegerType.java:82), causado por:
o Número de versión (@version) nulo
Collection was not processed by flush, causado por (varios motivos,
peliagudo):
o Envers, bags y malas anotaciones de envers.
o Jugar con las listas (utilizar add() a veces y sustituir las listas enteras al
mismo tiempo).
Llamo a persist() y no tengo id, causado por:
o persist() no asigna el id directamente
o -> usa save()
Errores típicos
•

•

No row with the given identifier exists (uff), causado por:
o Hay una entidad que apunta a una fila de la BD que ya no existe
o Modificaciones en paralelo de la colección
o Cascades delete/eliminaciones de elementos de la colección sin
actualizar el otro lado de la relación.
Hibernate me devuelve datos duplicados
Relaciones bidireccionales mal mapeadas
Cruces cartesianos sin Distinct.ROOT_ENTITY

•
•
Errores típicos
•

A collection with cascade delete-orphan was no longer referenced...
o Mala gestión de las colecciones:
Coleccion coleccion = miEntidad.getColeccion();
Coleccion coleccionNueva = new ColeccionImpl(coleccion);
miEntidad.setColeccion(coleccionNueva);

•

o -> add()
De principiante (y no tanto): constructor, @Entity, @Id...
Recapitulando...
Recapitulando...
•
•
•
•
•

¿Cómo es una clase persistente, una entidad?
o @Entity y @Id (Constructor [Serializable])
¿Cómo se especifica los metadatos de mapeos?
o Anotaciones | XML @OneToMany...
¿Qué relación hay entre identidad de objetos y de base de datos?
o Dentro de una sesión, son lo mismo. Si hay objetos detached -> no.
¿Qué tipos de herencia hay?
o 4 -> tablas única, 2 tablas (2), 3 tablas
¿Cuál es el ciclo de vida de un objeto persistente?
o Persistent -> Detached. Transient nuevo, Delete a eliminar
Recapitulando...
•
•

¿Cómo se busca y ordena?
o Criteria, HQL, SQL, anotaciones...
¿Cómo se recuperan objetos con asociaciones?
o @OneToMany... fetches
Recapitulando...
•

Preguntas de examen
o get() y load() -> Hibernate | JPA (lazy)
o save() / persist() / saveOrUpdate() -> = que antes, diferencias en
tratamiento en id.
o named SQL Query? -> query definida para reusar.
o SessionFactory? -> objeto único.. thread safe me da sesiones
o Session? Threadsafe? -> no...
o sorted/ordered collections? -> ordenada en memoria o no
Recapitulando...
•

Preguntas de examen
o transient/persistent/detached? -> estados de la entidad
o session.lock()? -> marcar entidad buena, bloquear BD
o second level cache? ->
o Constructor sin argumentos? -> no sabe qué crear...
o Hibernate Entity Class Final? -> es malo por rendimiento
o lazy initialization exception? ->
o N+1 selects? ->
Conclusiones
Ventajas e inconvenientes de los ORMs
•

Ideas?
o Te olvidas de la base de datos (buscar inserts o updates modificados)
o Y del SGBD (usando estándar SQL)
o Simplifica la gestión de inserciones/actualizaciones
o Otra herramienta/capa más
o 'Mapeos complejos'
o Conflictiva si no la usas bien
o ...
Ventajas de los ORMs
•
•
•
•
•

Diseño Orientado al Objeto puro (con pegas)
Separación de lógica y datos → Java EE, EJBs...
Productividad
o Operaciones en cascada
o Navegación
o Mapea una vez → CRUD completo
Separación de responsabilidades
Valor añadido (validación, envers...)
Inconvenientes de los ORMs
•
•
•
•
•

Necesitas conocimientos de SQL
Conviene “olvidarse del modelo” → modelo relacional “incorrecto”.
Se delega el control de las consultas
Modelo de dominio anémico
o Exposición de la implementación
o Separación de lógica y datos
o …
… “(…) the main thing is to be practical and stop paying too much attention
to lame patterns talk.”
Hibernate / JPA

Más contenido relacionado

PDF
Bases de Datos en Java - Intro a Hibernate
PPSX
Persistencia De Objetos(Hibernate)
PDF
Introducción práctica a JPA2
PPTX
Hibernate 3.2 short manual
PDF
Hibernate - JPA @luce 4
PPTX
Persistencia jpa
DOCX
Java persitence api
Bases de Datos en Java - Intro a Hibernate
Persistencia De Objetos(Hibernate)
Introducción práctica a JPA2
Hibernate 3.2 short manual
Hibernate - JPA @luce 4
Persistencia jpa
Java persitence api

La actualidad más candente (20)

PDF
Introduccion a Doctrine 2 ORM
PDF
Manual hibernate v2
PDF
Persistencia en Java - Serialización
PPSX
Java Persistence Api (Jpa)
PPT
ODP
Introducción a Java Persistence API
PPT
PERSISTENCIA BASADA EN ARCHIVOS
PPTX
Spring community day 2010
PDF
Tema 16 acceso a base de datos usando jpa por gio
PDF
Tema 9 aplicaciones de dos capas por gio
PDF
Tema 15 aplicaciones de dos capas por gio
PPTX
Java con base de datos
PPTX
Introducción a ORMs
PPTX
PPTX
Bases de datos orientado a objetos
PDF
Base de datos Objeto-Relacional.
PDF
Atributos
PDF
PPTX
Uml orientada a objetos
Introduccion a Doctrine 2 ORM
Manual hibernate v2
Persistencia en Java - Serialización
Java Persistence Api (Jpa)
Introducción a Java Persistence API
PERSISTENCIA BASADA EN ARCHIVOS
Spring community day 2010
Tema 16 acceso a base de datos usando jpa por gio
Tema 9 aplicaciones de dos capas por gio
Tema 15 aplicaciones de dos capas por gio
Java con base de datos
Introducción a ORMs
Bases de datos orientado a objetos
Base de datos Objeto-Relacional.
Atributos
Uml orientada a objetos
Publicidad

Destacado (7)

PPSX
Persistencia de objetos con Hibernate
PPT
PDF
J2ee (java ee) design patterns and architecture
PDF
Javantura v4 - Security architecture of the Java platform - Martin Toshev
PDF
Introduction to JPA and Hibernate including examples
PDF
New Features of JSR 317 (JPA 2.0)
PDF
Desarrollo de Aplicaciones Web II - Sesión 07: Transacciones
Persistencia de objetos con Hibernate
J2ee (java ee) design patterns and architecture
Javantura v4 - Security architecture of the Java platform - Martin Toshev
Introduction to JPA and Hibernate including examples
New Features of JSR 317 (JPA 2.0)
Desarrollo de Aplicaciones Web II - Sesión 07: Transacciones
Publicidad

Similar a Hibernate - JPA @luce 5 (20)

PDF
Hibernate - JPA @luce
PPTX
P2C2 Introducción a JEE5
PDF
Orm presentación final
PDF
06 - HIBERNATE sistema de informacion 1.pdf
PDF
Manual hibernate
DOC
Hibernate
PDF
Sesion03 apuntes
PDF
Hibernate - Introducción
PDF
Persistencia de datos en JAVA. Conversión JPA
PDF
Persistencia de datos en Java
PPTX
P2C5 Introducción a JEE5 - II
PDF
Manualjpa
PDF
Manualjpa
PDF
[ES] Manejadores de persistencia
PDF
Manual JPA
PPT
Spring ORM
PPT
Persistencia de datos_hibernate_arquitecturas_de_software
PDF
TopLink Jpa Parte 1 - Leonardo Torres Altez
PPTX
All about Spring Data JPA and similar concepts
Hibernate - JPA @luce
P2C2 Introducción a JEE5
Orm presentación final
06 - HIBERNATE sistema de informacion 1.pdf
Manual hibernate
Hibernate
Sesion03 apuntes
Hibernate - Introducción
Persistencia de datos en JAVA. Conversión JPA
Persistencia de datos en Java
P2C5 Introducción a JEE5 - II
Manualjpa
Manualjpa
[ES] Manejadores de persistencia
Manual JPA
Spring ORM
Persistencia de datos_hibernate_arquitecturas_de_software
TopLink Jpa Parte 1 - Leonardo Torres Altez
All about Spring Data JPA and similar concepts

Más de Javier Gamarra (12)

PDF
Performance myths in android
PDF
RxJava in practice
PDF
Cambiar una empresa con juegos ágiles
PDF
New Android Languages
PPTX
5 meses de juegos ágiles
PDF
Opinionated android
PDF
Arduino - Cuarta sesión
PDF
Arduino - Tercera sesión
PDF
Hibernate - JPA @luce 3
PDF
Hibernate - JPA @luce 2
PPT
Codemotion 2013
PPT
CAS 2013
Performance myths in android
RxJava in practice
Cambiar una empresa con juegos ágiles
New Android Languages
5 meses de juegos ágiles
Opinionated android
Arduino - Cuarta sesión
Arduino - Tercera sesión
Hibernate - JPA @luce 3
Hibernate - JPA @luce 2
Codemotion 2013
CAS 2013

Último (20)

PDF
Plantilla para Diseño de Narrativas Transmedia.pdf
PDF
Maste clas de estructura metálica y arquitectura
PPTX
historia_web de la creacion de un navegador_presentacion.pptx
PDF
Estrategia de apoyo tecnología grado 9-3
PDF
Estrategia de apoyo tecnología miguel angel solis
PPT
El-Gobierno-Electrónico-En-El-Estado-Bolivia
PDF
Calidad desde el Docente y la mejora continua .pdf
PPTX
RAP01 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
PDF
MÓDULO DE CALOR DE GRADO DE MEDIO DE FORMACIÓN PROFESIONAL
PPT
Que son las redes de computadores y sus partes
PDF
SAP Transportation Management para LSP, TM140 Col18
PPTX
REDES INFORMATICAS REDES INFORMATICAS.pptx
PPTX
RAP02 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
PPTX
COMO AYUDAN LAS TIC EN LA EDUCACION SUPERIOR.pptx
PDF
Liceo departamental MICRO BIT (1) 2.pdfbbbnn
DOCX
Zarate Quispe Alex aldayir aplicaciones de internet .docx
PPTX
Sesion 1 de microsoft power point - Clase 1
PDF
MANUAL TECNOLOGÍA SER MINISTERIO EDUCACIÓN
PDF
Influencia-del-uso-de-redes-sociales.pdf
PPTX
sa-cs-82-powerpoint-hardware-y-software_ver_4.pptx
Plantilla para Diseño de Narrativas Transmedia.pdf
Maste clas de estructura metálica y arquitectura
historia_web de la creacion de un navegador_presentacion.pptx
Estrategia de apoyo tecnología grado 9-3
Estrategia de apoyo tecnología miguel angel solis
El-Gobierno-Electrónico-En-El-Estado-Bolivia
Calidad desde el Docente y la mejora continua .pdf
RAP01 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
MÓDULO DE CALOR DE GRADO DE MEDIO DE FORMACIÓN PROFESIONAL
Que son las redes de computadores y sus partes
SAP Transportation Management para LSP, TM140 Col18
REDES INFORMATICAS REDES INFORMATICAS.pptx
RAP02 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
COMO AYUDAN LAS TIC EN LA EDUCACION SUPERIOR.pptx
Liceo departamental MICRO BIT (1) 2.pdfbbbnn
Zarate Quispe Alex aldayir aplicaciones de internet .docx
Sesion 1 de microsoft power point - Clase 1
MANUAL TECNOLOGÍA SER MINISTERIO EDUCACIÓN
Influencia-del-uso-de-redes-sociales.pdf
sa-cs-82-powerpoint-hardware-y-software_ver_4.pptx

Hibernate - JPA @luce 5

  • 3. Embedded • • • Clases que no tienen relación directa con una tabla (están contenidas dentro de otra tabla) o Ejemplo clásico: Usuario y dirección. Para mapear, @Embeddable para indicar que una clase se puede incluir dentro de otra y @Embedded para incluir dentro de una clase. Añadid dirección a las solicitudes o @Embeddable a la clase dirección (en vez de @Entity) o y @Embedded en el atributo dirección dentro de solicitud.
  • 5. Modos de identidad • • Identidad de Tabla: o @Id o Compuesto:  Varios @Id  @EmbeddedId (clase con @Embeddable y referencia con @EmbeddedId)  Id en otra clase y @IdClass en la tabla Probad cualquiera de estas referencias.
  • 6. Modos de identidad • • Por favor, usad una clave subrogada. Las claves compuestas sólo dan problemas o Pueden no ser inmutables o Los requisitos cambian y afectan a las claves o Son menos eficientes (ocupan más) o Son menos uniformes o Son incómodas en Java (varios setters) o Son peores en Hibernate
  • 7. Modos de identidad • • • Generación: o Identidad (DB2, MySQL, SQL Server...) o Secuencia o Tabla (hi/lo a una tabla) o Auto o 14 algoritmos más En base a @GeneratedValue y seleccionando la estrategia y el generador (@SequenceGenerator, entre otros). Probad @SequenceGenerator para ver las opciones de configuración.
  • 8. Modos de identidad • Además de un @Id puedes definir que una columna es un Id Natural: o … @NaturalId o buscar por natural id bySimpleNaturalId
  • 9. Modos de identidad • • • ¿Qué es la identidad? o Identidad de la BD o Identidad de Java Para una MISMA sesión, las dos cosas son lo mismo. Y fuera? Hibernate no garantiza igualdad.
  • 10. Modos de identidad • • Esto es importante en un par de casos sólo: o Composite Primary Key Class o 2 instancias de la misma clase en un Set en sesiones diferentes Implementa equals y hashCode, teniendo en cuenta que dos objetos diferentes pueden representar el mismo objeto en la base de datos.
  • 11. Modos de identidad • • • Repetimos... o Si usas primary keys compuestas o O si quieres unir entidades detached (luego veremos que es...) que reúsas en un Set Deberías implementar equals y hashCode: o Comparando por igualdad de negocio (columnas y valores que identifican univocamente a una entidad) https://community.jboss.org/wiki/EqualsAndHashCode
  • 13. Modos de locking • • • • Hasta ahora, sin saberlo, estamos trabajando con un modo last commit wins. Cuando vamos a trabajar con algo, Hibernate recupera la entidad de la base de datos. Si cuando guardamos los datos han cambiado, ese usuario pierde esa información. Podemos trabajar de forma optimista, al guardar Hibernate comprueba que no se han tocado las cosas. Si se han tocado da un error, si no, sigue con su trabajo.
  • 14. Modos de locking • Para activarlo, sólo tenemos que definir un atributo de tipo Integer anotado con @Version. o Podemos usar un Date también • Probadlo! • • En cualquier momento podemos llamar a un lock pesimista con session.lock() [Avanzado] Si tenéis tiempo... bloquead la inserción de una tabla.
  • 16. Herencia • • • Estrategias o Tabla por clase concreta  Con polimorfismo implícito  Con uniones o Tabla por jerarquía de clases o Tabla por subclase o Relaciones polimórficas + combinaciones de las anteriores JPA no soporta todo lo que soporta Hibernate
  • 17. Tabla por clase concreta con polimorfismo implícito
  • 18. Tabla por clase concreta con polimorfismo implícito • • Es simple, consultar contra clases concretas Contrapartidas… o Polimorfismo  Requiere una consulta por cada subclase concreta  Las asociaciones no se representan bien (no aceptan una FK simple) o Semánticas compartidas entre tablas o El esquema relacional no “conoce” la relación o No se puede hacer una asociación hacia la abstracta (ya que no es una entidad)
  • 19. Tabla por clase concreta con polimorfismo implícito @MappedSuperclass public abstract class AbstractPago @Entity public class PagoPAC extends AbstractPago @Entity public class PagoBeca extends AbstractPago
  • 20. Tabla por clase concreta con uniones
  • 21. Tabla por clase concreta con uniones • Permite relaciones hacia la clase abstracta • Consultas optimizables por el SGBD • Contrapartidas… o El esquema relacional no “conoce” la relación
  • 22. Tabla por clase concreta con uniones @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class AbstractPago @Entity public class PagoPAC extends AbstractPago @Entity public class PagoBeca extends AbstractPago
  • 24. Tabla por jerarquía • La mejor para el polimorfismo y para no polimorfismo • Contrapartidas… o Requiere columnas nullables en las subclases o Posible desperdicio de espacio o Requiere discriminador
  • 25. Tabla por jerarquía @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="tipo", discriminatorType=DiscriminatorType.STRING) public abstract class AbstractPago @Entity @DiscriminatorValue("PAC") public class PagoPAC extends AbstractPago @Entity @DiscriminatorValue("beca") public class PagoBeca extends AbstractPago
  • 27. Tabla por subclase • Basada en FKs • Esquema normalizado • Contrapartidas… o Complica el esquema o Ineficiente en jerarquías complejas* o Clase padre concreta
  • 28. Tabla por subclase @Entity @Inheritance(strategy = InheritanceType.JOINED) public abstract class AbstractPago @Entity public class PagoPAC extends AbstractPago @Entity public class PagoBeca extends AbstractPago
  • 29. Limitaciones de herencia • • Limitaciones oficiales Implementad alguna! o session.createCriteria(Petition.class) .list();
  • 30. Relaciones polimórficas • • • Permite mapear relaciones que no se podrían de otra forma: asociaciones polimórficas a clases desde múltiples tablas Sólo para situaciones muy especiales Contrapartidas… o No puede establecer FKs o Envers no lo soporta ☹
  • 31. Relaciones polimórficas public interface Cosa @Entity public class Beca implements Cosa @Entity public class Pago implements Cosa @Any(metaColumn = @Column(name = "tipo_de_cosa")) @AnyMetaDef(idType = "long", metaType = "string", metaValues = { @MetaValue(value = "Beca", targetEntity = Beca.class), @MetaValue(value = "Pago", targetEntity = Pago.class) }) @JoinColumn(name = "tipo_de_cosa_id") public Cosa getCosa() {
  • 33. Mapeos 'complejos' • @SecondaryTables + @SecondaryTable + @PrimaryKeyJoinColumn • @Parent • @Target • @NotFound
  • 35. Batch Processing • ¿Qué pasa si lanzamos esto? Transaction tx = session.beginTransaction(); for ( int i=0; i<100000; i++ ) { Petition petition = new Petition(.....); session.save(petition); } tx.commit(); session.close();
  • 36. Batch Processing • • Hibernate se queda sin memoria. Podemos arreglarlo, haciendo operaciones en batch: o Activando hibernate.jdbc.batch_size (en persistence/hibernate.cfg.xml) y poniendolo a un valor entre 10-50
  • 37. Batch Processing Transaction tx = session.beginTransaction(); for ( int i=0; i<100000; i++ ) { Petition petition = new Petition(.....); session.save(petition); if ( i % 20 == 0 ) { //el valor de la propiedad session.flush(); session.clear(); } } tx.commit(); session.close();
  • 38. Batch Processing • • • Stateless Session o Sin caché de primer nivel o Sin caché de segundo nivel o Sin dirty checking/write behind o Sin cascades o Sin interceptores o Similar a JDBC Scrollable HQL
  • 39. Batch Processing • • En estrategias de Fetch hay una adicional (cuarta) o @BatchSize, recupera sentencias en bloque. MUY interesante... o soluciona el problema de los N+1 fetches.
  • 41. Servicios • Un sistema de extensión (similar a plugins) de Hibernate. o Desde Hibernate 4.0 o Permite el registro de servicios/implementaciones alternativas para, por ejemplo:  TransactionFactory (transacciones)  JtaPlatform (gestión de JTA)  JndiService  JdbcServices  ConfigurationService  ...
  • 43. Transitividad • Cascades de JPA: o CascadeType.PERSIST: cascada de persists o CascadeType.MERGE: cascadas de merges o CascadeType.REMOVE: cascade de eliminaciones o CascadeType.REFRESH: cascade de refresh (volver a leer una entidad de BD) o CascadeType.DETACH: cascade de detach (desunir de sesión) o CascadeType.ALL: todos los de arriba
  • 44. Transitividad • Cascades de Hibernate (@Cascade): o save-update... o delete o lock o replicate (copiar un objeto, muy muy raro) o evict o delete-orphan
  • 45. Transitividad • • Delete orphan es interesante: o Sólo aplica a oneToMany. o Cuando elimino un elemento hijo de la colección indico que quiero eliminarlo de la BD porque se ha quedado huérfano. o orphanRemoval en @OneToMany.  No estoy haciendo esto: session.remove()  padre.geHijos().remove(0) o No cuenta para Cascade.ALL. o @OneToMany(orphanRemoval = true) Probadlo!
  • 46. Transitividad • Recomendaciones de cascade: o Es más lógico en relaciones @OneToOne y @OneToMany (padre con hijos) o Si el objeto hijo en un @OneToMany no tiene sentido sin el padre -> Cascade.ALL y orphanRemoval o Típicos: persist, save-update...
  • 48. Caching • • • Caché de primer nivel o get() y load() me recuperan objetos que tienen en la sesión... Caché de segundo nivel Caché de queries o Hibernate tiene en cuenta cambios en los objetos que se muestran en las consultas. o Depende del patrón de uso de la aplicación.
  • 49. Caching • Caché de segundo nivel: o Muy común, Hibernate se integra muy bien con varios proveedores de caché. o Típico para tablas de referencia (provincia, localidad, datos maestros...) o Marcar entidades interesadas (o colecciones): @Cacheable o @Cache(usage = CacheConcurrencyStrategy.TIPO_DE_CACHING)
  • 50. Caching • Tipos de Caching: o NONE o READ_ONLY: no se modifican a menudo... o NONSTRICT_READ_WRITE: pocas transacciones apuntando al mismo item... o READ_WRITE: actualizaciones frecuentes. o TRANSACTIONAL
  • 51. Caching • Típicos proveedores: o EHCache: soporta todos los tipos de caching o Infinispan: read-only, transactional
  • 52. Caching • Queries: o Activar use_query_cache o Establecer el tiempo de timeout o Establecer las queries que quieres cachear  setCacheable(true)
  • 54. Performance • • Hibernate no es lento. Recomendaciones de rendimiento: o Tener en cuenta las 4 estrategias de fetching (Select, Subselect, Join, BatchSize) o Cuidado con N+1 o Fetch-profiles (para personalizar escenarios de búsqueda) o Personalizar Fetch en Criterias (criteria.setFetchMode("propiedad",MODO)) EAGER=JOIN, LAZY=SELECT  Probadlo!"
  • 55. Performance • • • Tres grandes tipos de colecciones: o indexed collections (mapas, listas, arrays) o sets o bags Las dos primeras son las más eficientes en save/remove/update de elementos. Bags y lists son más eficientes en @OneToMany con mappedBy
  • 56. Performance • • One-shot-delete o Imaginemos que tenemos 20 elementos, eliminamos 18 y añadimos 3 o Podemos borrar 18 elementos (1 a 1) e insertar 3 o Eliminar todo e insertar 5  En este caso conviene hacer clear(); Probadlo!
  • 57. Performance • • Marcar claves naturales @NaturalId (puede mejorar rendimiento al acceder a ellas) Realizar mapeos sencillos (los que hemos visto)
  • 58. Performance • Si realiza muchas consultas: o plantear estrategias estilo JOIN/SUBSELECT o Activar batch o utilizar @BatchSize o Activar caché de segundo nivel o HQL o SQL o Query cache
  • 59. Performance • Si realiza una consulta muy pesada: o Eliminar cruces JOIN (empezando por colecciones) o Poner asociaciones *ToOne a Lazy (con Select o Subselect) o Índices o HQL o SQL o Query cache
  • 61. Validaciones • • Hibernate se complementa con Hibernate Validator Es la base de Bean Validation, un estándar Java EE 6 o @NotNull o @Past o @Size o @Pattern o @Max o @Email o @CreditCardNumber
  • 62. Validaciones • • Incluid las librerías de validation (es más sencillo en Java EE) o Añadid una anotación y probad a guardar. Podemos llamar a los validadores con: ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set<ConstraintViolation<User>> constraintViolations = validator.validate(user); • Probadlo!
  • 64. Envers • • • Librería de auditoría. Para activar la versión "básica" basta con: o Copiar la librería o @Audited o Cuidado con relaciones: @NotAudited (de momento) Probadlo!
  • 65. Envers • Puedo hacer queries específicas: AuditQuery query = AuditReaderFactory.get(session) .createQuery() .forEntitiesAtRevision(MyEntity.class, revisionNumber); query.uni../getResu..() • Probadlo!
  • 66. Envers • Dos estrategias, start y start-end • Puedo guardar el usuario o información adicional • Las querys pueden llegar a ser complejas: List personsAtAddress = getAuditReader().createQuery() .forEntitiesAtRevision(Person.class, 12) .addOrder(AuditEntity.property("surname").desc()) .add(AuditEntity.relatedId("address").eq(addressId)) .setFirstResult(4) .setMaxResults(2) .getResultList();
  • 67. Envers • Puedo preguntar a una entidad por las revisiones que ha tenido Number revision = (Number) getAuditReader().createQuery() .forRevisionsOfEntity(MyEntity.class, false, true) .setProjection(AuditEntity.revisionNumber().min()) .add(AuditEntity.id().eq(entityId)) .add(AuditEntity.revisionNumber().gt(42)) .getSingleResult(); • Probadlo!
  • 68. Envers • • Envers es más quisquilloso en algún tipo concreto de mapeos: o Bags o @OneToMany+@JoinColumn, mappedBy (necesita @AuditJoinTable) o @OneToMany+@JoinColumn, insertable=false, updatable = false (necesita @AuditMappedBy) Siempre se puede decidir no auditar una relación con @NotAudited.
  • 70. Multi-tenancy • Una aplicación que sirve múltiples clientes. • Típico de SaaS (Software as Service: google docs) • Cada cliente sólo debe poder ver sus datos o Base de datos diferente, JDBC que cambia o Esquema separado, schema que cambia al conectarse o Única base de datos, discriminador
  • 71. Multi-tenancy • • En Hibernate: Session session = sessionFactory.withOptions() .tenantIdentifier( yourTenantIdentifier ) .openSession(); Opciones de identificador: o DATABASE o SCHEMA o DISCRIMINATOR (No soportada aún, Hibernate 5)
  • 73. ¿ Qué más es Hibernate?
  • 74. ¿Qué más es Hibernate? • • • • • • • • • • Core Shards: fragmentación horizontal Search: búsqueda de texto completo (Lucene) Tools Validator: validación de datos Metamodel Generator OGM Annotations Entity Manager: operaciones y ciclo JPA Envers: versionado e histórico
  • 76. Recomendaciones • • No utilices claves compuestas o Claves surrogadas siempre, ni naturales ni compuestas En el import.sql (ficheros sql que carga Hibernate directamente), los ids, negativos (para no hacer conflicto con ids generados) • No uses herencia, usa agregación (GoF) • No uses mapas, usa entidades y relaciones
  • 77. Recomendaciones • • • • Cuando estés mapeando por primera vez, hacer tests (incluso vacíos) está bien: o No arrancas el servidor de aplicaciones! Ojo con los "lazos" en los modelos y las relaciones bidireccionales... Se puede implementar SoftDelete (@SQLDelete) o restricciones globales de búsqueda (@Where) Puedo ver los valores de las consultas (?) -> en log4j, org.hibernate.type a TRACE.
  • 78. Errores típicos • Lazy Initialization Exception, causado por: o Intentar cargar desde la vista/lógica con la sesión cerrada una lista de objetos/objeto con fetch a LAZY. o -> Hibernate.initialize() o -> Activar lazy load sin transacciones: hibernate.enable_lazy_load_no_trans o -> OpenSessionInView o -> Conversaciones
  • 79. Errores típicos • • Detached entity passed to persist, causado por: o Fijar un id manualmente a una entidad que utiliza un auto-generado o Sin cascadas, intentar guardar una relación de un objeto que no está en la base de datos. o Llamada persist() o save() de un objeto que ya está en la BD Cannot Open Connection, causado por: o Malos valores de conexión a la BD.
  • 80. Errores típicos • • • NPE en IntegerType.next(IntegerType.java:82), causado por: o Número de versión (@version) nulo Collection was not processed by flush, causado por (varios motivos, peliagudo): o Envers, bags y malas anotaciones de envers. o Jugar con las listas (utilizar add() a veces y sustituir las listas enteras al mismo tiempo). Llamo a persist() y no tengo id, causado por: o persist() no asigna el id directamente o -> usa save()
  • 81. Errores típicos • • No row with the given identifier exists (uff), causado por: o Hay una entidad que apunta a una fila de la BD que ya no existe o Modificaciones en paralelo de la colección o Cascades delete/eliminaciones de elementos de la colección sin actualizar el otro lado de la relación. Hibernate me devuelve datos duplicados Relaciones bidireccionales mal mapeadas Cruces cartesianos sin Distinct.ROOT_ENTITY • •
  • 82. Errores típicos • A collection with cascade delete-orphan was no longer referenced... o Mala gestión de las colecciones: Coleccion coleccion = miEntidad.getColeccion(); Coleccion coleccionNueva = new ColeccionImpl(coleccion); miEntidad.setColeccion(coleccionNueva); • o -> add() De principiante (y no tanto): constructor, @Entity, @Id...
  • 84. Recapitulando... • • • • • ¿Cómo es una clase persistente, una entidad? o @Entity y @Id (Constructor [Serializable]) ¿Cómo se especifica los metadatos de mapeos? o Anotaciones | XML @OneToMany... ¿Qué relación hay entre identidad de objetos y de base de datos? o Dentro de una sesión, son lo mismo. Si hay objetos detached -> no. ¿Qué tipos de herencia hay? o 4 -> tablas única, 2 tablas (2), 3 tablas ¿Cuál es el ciclo de vida de un objeto persistente? o Persistent -> Detached. Transient nuevo, Delete a eliminar
  • 85. Recapitulando... • • ¿Cómo se busca y ordena? o Criteria, HQL, SQL, anotaciones... ¿Cómo se recuperan objetos con asociaciones? o @OneToMany... fetches
  • 86. Recapitulando... • Preguntas de examen o get() y load() -> Hibernate | JPA (lazy) o save() / persist() / saveOrUpdate() -> = que antes, diferencias en tratamiento en id. o named SQL Query? -> query definida para reusar. o SessionFactory? -> objeto único.. thread safe me da sesiones o Session? Threadsafe? -> no... o sorted/ordered collections? -> ordenada en memoria o no
  • 87. Recapitulando... • Preguntas de examen o transient/persistent/detached? -> estados de la entidad o session.lock()? -> marcar entidad buena, bloquear BD o second level cache? -> o Constructor sin argumentos? -> no sabe qué crear... o Hibernate Entity Class Final? -> es malo por rendimiento o lazy initialization exception? -> o N+1 selects? ->
  • 89. Ventajas e inconvenientes de los ORMs • Ideas? o Te olvidas de la base de datos (buscar inserts o updates modificados) o Y del SGBD (usando estándar SQL) o Simplifica la gestión de inserciones/actualizaciones o Otra herramienta/capa más o 'Mapeos complejos' o Conflictiva si no la usas bien o ...
  • 90. Ventajas de los ORMs • • • • • Diseño Orientado al Objeto puro (con pegas) Separación de lógica y datos → Java EE, EJBs... Productividad o Operaciones en cascada o Navegación o Mapea una vez → CRUD completo Separación de responsabilidades Valor añadido (validación, envers...)
  • 91. Inconvenientes de los ORMs • • • • • Necesitas conocimientos de SQL Conviene “olvidarse del modelo” → modelo relacional “incorrecto”. Se delega el control de las consultas Modelo de dominio anémico o Exposición de la implementación o Separación de lógica y datos o … … “(…) the main thing is to be practical and stop paying too much attention to lame patterns talk.”