Arquitectura de Aplicaciones Empresariales en Java Relator: Juan Claudio Navarro jcnavarro@optimisa.cl, jnavarro@dcc.uchile.cl, juancla.navarro@gmail.com Agenda n Bloque 1 (18:30 – 20:00) n n n n Java EE La capa de presentación La capa de negocio Bloque 2 (20:30 – 21:30) n n La capa de datos Discusión 2 JAVA EE 3 Aplicaciones Empresariales n Las aplicaciones empresariales suelen presentar algunos de los siguientes requerimientos Interacción con diversas fuentes de datos n Interacción con otros sistemas (actuales y/o legados) n Acceso Web n Concurrencia n Alta carga de procesamiento n Usuarios con diferentes perfiles n Requerimientos de seguridad n 4 Java Platform, Enterprise Edition n n Java EE es la plataforma de Java para el desarrollo de aplicaciones en el servidor (anteriormente llamada J2EE: Java 2, Enterprise Edition) Provee un ambiente de ejecución y un conjunto de APIs: Servlets, JSP, JSF, EJB, JMS, JDBC, JPA, JNDI, JavaMail, JAXB, JAXP, JAX-WS, etc. 5 Beneficios de Java EE n n n n n n n Transparencia de la ubicación Visión OO de la base de datos Manejo transaccional Pools de recursos Seguridad Alta disponibilidad Portabilidad 6 Contenedores Java EE n La especificación Java EE define dos contenedores: n n n Web Container EJB Container Estos contenedores son los responsables de manejar los componentes correspondientes 7 Servidores Java EE Servidor Proveedor Tipo Weblogic Server Oracle (antes BEA) comercial WebSphere Application Server IBM comercial Tomcat Apache libre Sólo Web Container JBoss Application Server Red Hat (antes JBoss) libre EJB Container, se integra con Tomcat GlassFish Oracle (antes Sun) libre JOnAS OW2 Consortium libre n n Notas EJB Container, se integra con Tomcat Lista de servidores en http://en.wikipedia.org/wiki/Comparison_of_application_servers Análisis de Gartner sobre servidores de aplicaciones: http://www.gartner.com/technology/reprints.do? id=1-17GUO5Z&ct=110928&st=sb 8 Servlets JSP – JavaServer Pages JSF – JavaServer Faces Otras tecnologías: ZK LA CAPA DE PRESENTACION 9 La Capa Web n La operación de la capa Web es soportada por el contenedor Web n n n Maneja la interacción con el cliente (protocolo HTTP(S)) Reenvía cada requerimiento HTTP al componente Web que corresponda, entregándole los parámetros necesarios para que éste pueda realizar su tarea Maneja sesiones, filtros, eventos, seguridad, etc. 10 Servlets n n El contenedor Web maneja la interacción con los clientes Web (browser’s), y delega los requerimientos dinámicos a componentes Web (servlets y páginas JSP) Un servlet es una clase Java que es instanciada e invocada por el contenedor Web, en respuesta a requerimientos HTTP 11 Servlets n Tareas que puede realizar un servlet n n n n n n Leer data enviada por el usuario (por ejemplo a través de un Form de una página Web) Obtener otra información del requerimiento (browser utilizado, cookies, dirección IP cliente, etc.) Generar el resultado Formatear el resultado en un documento (típicamente una página HTML) Establecer parámetros de respuesta (tipo de documento retornado, cookies, etc.) Enviar la respuesta al cliente (formato text/html, image/gif, etc.) 12 Servlets - un Ejemplo Sencillo ServletHolaMundo.java WEB-INF/web.xml public class ServletHolaMundo extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Hola, mundo!</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Hola, mundo!</h1>"); out.println("</body>"); out.println("</html>"); out.close(); } } <servlet> <servlet-name>ServletHolaMundo </servlet-name> <servlet-class>cl.servlets.ServletHolaMundo </servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletHolaMundo </servlet-name> <url-pattern>/holamundo </url-pattern> </servlet-mapping> 13 Limitaciones de Servlets n Con Servlets, es fácil: n n n n n Leer parámetros y form data Manejar cookies y sesiones Manejar HTTP: request/response headers, códigos de estado Compartir datos entre servlets Pero no resulta cómodo: n n Usar sentencias println para generar HTML Mantener el código HTML 14 JSP – JavaServer Pages n n La tecnología JSP facilita la construcción de aplicaciones Web dinámicas Una página JSP (JavaServer Pages) es un documento de texto que incluye dos tipos de texto: n n Texto estático (template data), que puede ser expresado en cualquier formato basado en texto (HTML, XML, WML, etc.) Elementos JSP, que construyen contenido dinámico Página JSP Página HTML generada en request time y enviada al cliente Página HTML desplegada en el browser 15 Páginas JSP n n El contenedor Web genera un servlet a partir de una página JSP Elementos JSP al interior de una página n Elementos de scripting n n n n n n Scriptlets: <% código Java %> Expresiones Java: <%= expresión Java %> Declaraciones: <%! declaraciones Java %> Expression Language: ${ expresión } Otros: directivas, custom tags, etc. Objetos predefinidos en una página JSP: request, response, out, session, application, exception 16 JSF – JavaServer Faces n n n JSF es el framework para la capa de presentación provisto por Java EE JSF provee una arquitectura para manejar el estado de componentes, procesamiento de información, validación de información ingresada por el usuario, atención de eventos, y navegación entre páginas JSF separa la lógica de presentación y de aplicación, facilitando la conexión entre las correspondientes capas 17 JSF – Eventos y Navegación Página JSP Managed bean Flujo de navegación (facesconfig.xml) ... <h:inputText value="#{algoritmoBean.iteraciones}"/> <h:commandButton value="Calcular" action="#{algoritmoBean.calcular}"/> public class Algoritmo { private int iteraciones = 10; public int getIteraciones() { return iteraciones; } public int setIteraciones(int n) { iteraciones = n; } public String calcular() { for (int i=0; i<iteraciones; i++) {…}; return "ok"; } } evento outcome <managed-bean> <managed-bean-name>algoritmoBean</managed-bean-name> <managed-bean-class>modelo.algoritmos.Algoritmo</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>algoritmo.jspx</from-view-id> <navigation-case> <from-outcome>ok</from-outcome> <to-view-id>home.jspx</to-view-id> </navigation-case> </navigation-rule> 18 ZK – http://www.zkoss.org n ZK Framework permite construir Rich Internet Applications (RIA) haciendo uso de Ajax de manera transparente para el programador 19 ZK Spreadsheet Demo 20 EJB – Enterprise JavaBeans Session Beans Message-Driven Beans Otras tecnologías: Spring LA CAPA DE NEGOCIO 21 EJB - Enterprise JavaBeans n n n Un Enterprise JavaBean es un componente que opera en el servidor, y que encapsula lógica de negocio de una aplicación La tecnología de EJB’s provee servicios de nivel de sistema (distribución, transacciones, pools de objetos, …), permitiendo que el programador se concentre en la lógica de negocio La especificación de EJB 3 (mayo 2006) incorporó el uso de anotaciones e inyección de dependencias, simplificando el desarrollo 22 Tipos de EJB n Existen 2 tipos de EJB n n Session Beans Message-Driven Beans (MDB) Session Bean Message-Driven Bean Invocación Sincrónica Asincrónica: el cliente envía un mensaje JMS a una cola, y el servidor invoca al MDB de manera asíncrona para procesar el mensaje Interfaz Local y/o remota No requiere, el cliente no invoca al MDB 23 Session Beans n n n n Un session bean representa una sesión de trabajo de un cliente al interior del servidor de aplicaciones El cliente invoca sincrónicamente los métodos del bean No hay concurrencia en session beans: si varios clientes ejecutan simultáneamente operaciones de un mismo session bean, cada uno de ellos opera con una instancia diferente del bean Dos tipos de session beans: n Stateless (SLSB): n n n n No mantiene estado conversacional para el cliente El servidor crea un pool de instancias para cada SLSB Cuando un cliente invoca un método de un SLSB, el servidor escoge una instancia del pool para atender el requerimiento, y luego la instancia vuelve al pool Stateful (SFSB): n n Mantiene estado conversacional en variables de instancia Una instancia de un stateful session bean pertenece a un cliente, y permanece asociado a él hasta que se da por terminada la sesión 24 Elementos de un Session Bean n Un session bean se define mediante: n n n La interfaz de negocio (business interface) La clase de implementación, que implementa la interfaz de negocio La interfaz de negocio puede ser: n n Local: utilizada por clientes locales (que se ejecutan en la misma instancia del servidor de aplicaciones), con semántica Java Remote: utilizada por clientes Java remotos que interactúan con el bean mediante RMI 25 Objetos Remotos n n n n n EJB utiliza RMI (Remote Method Invocation) para la invocación de objetos remotos El cliente invoca un stub (proxy del objeto remoto, en el cliente) El stub invoca al skeleton a través de la red (proxy del objeto remoto, en el servidor) El skeleton invoca al objeto remoto El stub y el objeto remoto implementan la misma interfaz, por lo que el cliente opera como si interactuara directamente con el objeto remoto 26 Un Session Bean n ServicioFacturas.java package cl.sii.facturaelectronica; n n Interfaz de negocio La anotación @Local indica que el bean soporta acceso local La anotación @Remote indica que el bean soporta acceso remoto @Local public interface ServicioFacturas { boolean valida(Factura factura); } ServicioFacturasBean.java n package cl.sii.facturaelectronica; n Clase de implementación Las anotaciones @Stateless y @Stateful indican que se trata de un session bean @Stateless public class ServicioFacturasBean implements ServicioFacturas { @Override public boolean valida(Factura factura) { ... } } 27 Un Cliente Local n En un componente de una aplicación Java EE (un servlet, un EJB, etc.), la anotación @EJB inyecta la interfaz de negocio FacturaServlet.java ... import javax.ejb.EJB; ... public class FacturaServlet extends HttpServlet { @EJB private ServicioFacturas ejb; ... private void procesar(Factura factura) { if (ejb.valida(factura)) { ... } } } 28 Un Cliente Remoto (WebLogic) n Los clientes remotos utilizan JNDI para acceder a session beans ClienteServicioFacturas.java ... public class ClienteServicioFacturas { public void valida(Factura factura) throws NamingException { // Obtenemos el contexto inicial Properties properties = new Properties(); properties.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory"); properties.put(Context.PROVIDER_URL, "t3://facturas.sii.cl:7001"); Context context = new InitialContext(properties); // Obtenemos una referencia a un EJB y lo utilizamos ServicioFacturasRemote ejb = (ServicioFacturasRemote) context.lookup("FacturaApp/ServicioFacturas/remote"); if (ejb.valida(factura)) { ... } } } 29 Interfaces Locales v/s Remotas n n n n Las invocaciones remotas (diferentes procesos) son mucho más caras que las locales Lo anterior se acentúa si los procesos se encuentran en máquinas diferentes Por lo tanto, las interfaces remotas deben diseñarse de modo de minimizar las invocaciones Recomendaciones de Martin Fowler (Patterns of Enterprise Application Architecture) n n n Primera ley de Diseño de Objetos Distribuidos: no distribuya sus objetos J En general, para hacer uso de varios nodos utilice clustering: replique los procesos completos Es frecuente realizar una separación física entre la capa Web y la capa de negocio, en este caso preocúpese de minimizar la interacción entre las capas 30 Message-Driven Beans (MDB) n n n n Un message-driven bean permite atender requerimientos asincrónicos en la plataforma Java EE A diferencia de session beans, los MDB no poseen interfaces de negocio, debido a que los clientes no manejan referencias al bean En lugar de ello, los clientes envían mensajes a sistemas de mensajería (Websphere MQ, etc.), y éstos son atendidos por objetos MDB No hay concurrencia en objetos MDB: si se procesan simultáneamente mensajes de un mismo destino, cada uno de ellos es procesado por una instancia diferente del bean 31 Un Cliente JMS n El siguiente código envía un mensaje JMS a una cola, utilizando JNDI para acceder a los recursos // Inicio de una sesión JMS ConnectionFactory factory = (ConnectionFactory) context.lookup("jms/QCF"); Connection connection = factory.createConnection(); Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); // Creación de un MessageProducer asociado a un destino Destination destination = (Destination) context.lookup("jms/QProcesos"); MessageProducer producer = session.createProducer(destination); // Envío del mensaje producer.send(session.createObjectMessage(object)); session.commit(); // Cierre de la conexión connection.close(); 32 Un Message-Driven Bean n n n El método onMessage() procesa el mensaje Si se produce un commit en la transacción, el mensaje es consumido (es eliminado del destino) Si se produce un rollback en la transacción, el mensaje no es consumido (permanece en el destino) @MessageDriven( messageListenerInterface=MessageListener.class, activationConfig = { @ActivationConfigProperty( propertyName="connectionFactoryJndiName", propertyValue="jms/QCF"), @ActivationConfigProperty( propertyName="destinationName", propertyValue="jms/QProcesos"), @ActivationConfigProperty( propertyName="destinationType", propertyValue="javax.jms.Queue") }) public class QProcesosBean implements MessageListener { public void onMessage(Message message) { ... } } 33 Una Alternativa a EJB: Spring n n n n Spring (http://www.springsource.com/developer/spring) es un framework que, entre otras cosas, entrega algunas de las funcionalidades provistas por EJBs (transacciones, integración con JPA, acceso remoto, etc.), sin requerir el uso de ellos La ventaja de no usar EJB es que se simplifican las pruebas: Spring se integra de manera natural con JUnit Spring opera sobre un contenedor de Inversión de Control, que permite configurar el “cableado” de componentes Java: los objetos se conocen entre sí mediante interfaces; Spring instancia los objetos que implementan las interfaces a partir de la configuración, y establece las referencias entre objetos Los objetos manejados por Spring pueden tener los siguientes scopes: n n n n n Singleton (default) Prototype (se crea un nuevo objeto cada vez que se solicita uno) Session Request Desktop (en ZK, corresponde a las páginas de un requerimiento) 34 Transacciones JPA – Java Persistence API LA CAPA DE DATOS 35 Transacciones n n n n La tecnología EJB provee Container-Managed Transactions En la figura, “method-A” inicia una transacción, y al interior de ella invoca a “method-B” El método “method-B”, ¿se ejecutará en la misma transacción o en una nueva? La respuesta a la pregunta anterior está dada por el atributo transaccional de “method-B” 36 Atributos Transaccionales Atributo Descripción Required (default) Si el cliente se ejecuta en una transacción, se usa esa transacción. De lo contrario, se inicia una transacción nueva. RequiresNew Se inicia una transacción nueva. Si el cliente se ejecuta en una transacción, ésta es suspendida y retomada al finalizar el método invocado. Mandatory El método se ejecuta en la transacción del cliente. Si no hay una transacción en el cliente, se genera una excepción TransactionRequiredException. NotSupported El método es invocado con un contexto transaccional no especificado. Si el cliente se ejecuta en una transacción, ésta es suspendida y retomada al finalizar el método invocado. Supports Se ejecuta en la transacción del cliente si ésta existe (Required), de lo contrario el método es invocado con un contexto transaccional no especificado (NotSupported). Never Si el cliente se ejecuta en una transacción, se genera una excepción EJBException. 37 Especificación de Atributos n La anotación @TransactionAttribute permite establecer un atributo transaccional diferente del default REQUIRED @Stateless public class TestFacturasBean implements TestFacturas { @PersistenceContext private EntityManager em; @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void creaFactura() { Factura factura = new Factura(); ... em.persist(factura); } } 38 Alcance de una Transacción n n n Usando Container-Managed Transaction Demarcation, las transacciones son iniciadas por el servidor en función del atributo transaccional del método invocado La transacción es finalizada por el servidor cuando termina el método cuya invocación causó el inicio de la transacción El contenedor cancela la transacción (Rollback) si: n n n n Durante la ejecución del método se ha invocado al método EJBContext.setRollbackOnly() La ejecución del método genera una excepción de sistema La ejecución del método genera una excepción de aplicación declarada @ApplicationException(rollback=true) En caso contrario, la transacción es aceptada (Commit) 39 Transacciones Distribuidas n n El servidor Java EE provee soporte para el manejo de transacciones distribuidas (operaciones con diferentes RDBMS, y desde diferentes servidores Java EE, en una única transacción) Si se utiliza Container-Managed Transaction Demarcation, el servidor Java EE maneja automáticamente el protocolo twophase commit en la interacción con las bases de datos (para lo cual los drivers deben soportar el protocolo XA) Transacción incluye 3 RDBMS 40 Integración con JMS n n n El uso de mensajería se integra de manera natural con el modelo transaccional de Java EE En el primer ejemplo, el EJB X envía un mensaje a la cola A, y modifica la base de datos B, y finalmente el EJB Y modifica la base de datos C, todo ello en una misma transacción En el segundo ejemplo, la transacción realizada por el EJB X incluye el consumo de un mensaje de la cola A, y la actualización de las bases de datos B y C 41 JPA – Java Persistence API n n n n JPA es el framework de persistencia de Java EE Provee un mecanismo de mapeo objetorelacional que permite al programador Java utilizar un modelo de dominio para interactuar con una base de datos relacional Principales proveedores de persistencia: Hibernate, TopLink, Kodo, Apache OpenJPA Beneficios: simplicidad, productividad, mantenibilidad 42 Características JPA n n n n n n n Modelo de persistencia basado en POJOs Entidades pueden ser serializables Herencia Polimorfismo Mapeo vía anotaciones o XML Soporte de Java EE y Java SE Proveedores de persistencia “pluggables” 43 Entidades n n n n n n n n n Una entidad es una clase persistente, liviana, del modelo de dominio Puede ser una clase concreta o abstracta Se mapea a una tabla Sus campos o propiedades se mapean a columnas de la tabla Tiene un identificador persistente Puede tener estado persistente y transiente Soporta herencia y polimorfismo Puede ser serializable Las asociaciones entre entidades se manejan a través de referencias y colecciones 44 Entidades n n n n n La anotación @Table permite definir el nombre de la tabla (puede omitirse si la tabla se llama igual que la clase) El mapeo de columnas puede realizarse sobre campos o propiedades La anotación @Column permite definir el nombre de la columna (puede omitirse si la columna se llama igual que el campo/propiedad) La anotación @Id permite indicar que la columna corresponde a la llave primaria Las anotaciones @GeneratedValue y @SequenceGenerator permiten indicar el uso de una secuencia @Entity @Table(name="EMPRESAS") public class Empresa { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_EMP_G") @SequenceGenerator(name="SEQ_EMP_G", sequenceName="SEQ_EMP", allocationSize=1) private long id; EMPRESAS } private String rut; ID RUT RAZON_SOCIAL @Column(name="RAZON_SOCIAL") private String razonSocial; 2 77.234.556-2 Restorán El Poroto S.A. 5 89.188.652-4 Librería Macondo 45 Asociaciones n n Pueden ser unidireccionales o bidireccionales Es posible definir asociaciones: n n n n n n 1-1: @OneToOne 1-n: @OneToMany n-1: @ManyToOne n-n: @ManyToMany Se implementan mediante referencias y la librería de colecciones de Java: Collection, List, Set, Map Se puede definir la propagación de operaciones en cascada: n n n n n PERSIST REMOVE MERGE REFRESH ALL 46 Asociación @ManyToOne n n La anotación @ManyToOne indica que el campo/propiedad es una referencia a una instancia de otra entidad La anotación @JoinColumn permite indicar los nombres de las columnas que definen la asociación EMPLEADOS ID RUT NOMBRE ID_EMPR @Entity @Table(name="EMPLEADOS") 1 9.345.222-4 Carlos Rojas 2 public class Empleado { 8 8.336.235-6 Daniela Merino 2 @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_EMPL_G") @SequenceGenerator(name="SEQ_EMPL_G", sequenceName="SEQ_EMPL", allocationSize=1) private long id; private String rut; private String nombre; @ManyToOne @JoinColumn(name="ID_EMPR", referencedColumnName="ID") private Empresa empresa; } 47 Asociación @OneToMany n n La anotación @OneToMany indica que el campo/ propiedad es una colección de instancias (Set, List) de otra entidad El atributo mappedBy indica el nombre del campo/ propiedad en la otra entidad de la asociación @Entity @Table(name="EMPRESAS") public class Empresa { ... @OneToMany(mappedBy="empresa") private Set<Empleado> empleados; } 48 Herencia n Una entidad puede extender: Una entidad abstracta o concreta n Una clase (no entidad) abstracta o concreta n n JPA soporta 3 estrategias de herencia: SINGLE_TABLE: una tabla para la jerarquía n JOINED: una tabla para cada entidad (abstracta o concreta) de la jerarquía n TABLE_PER_CLASS (opcional): una tabla para cada clase concreta n 49 Herencia – SINGLE_TABLE @Entity @Table(name="PERSONA") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="TIPO", discriminatorType=DiscriminatorType.STRING, length=2) public abstract class Persona { @Id private long id; private String rut; } @Entity @DiscriminatorValue(value="PN") public class PersonaNatural extends Persona { private String nombre; } @Entity @DiscriminatorValue(value="PJ") public class PersonaJuridica extends Persona { @Column(name="RAZON_SOCIAL") private String razonSocial; } 50 Herencia – JOINED @Entity @Table(name="PERSONA") @Inheritance(strategy=InheritanceType.JOINED) public abstract class Persona { @Id private long id; private String rut; } @Entity @Table(name="PERSONA_NATURAL") public class PersonaNatural extends Persona { private String nombre; } @Entity @Table(name="PERSONA_JURIDICA") public class PersonaJuridica extends Persona { @Column(name="RAZON_SOCIAL") private String razonSocial; } 51 Herencia – TABLE_PER_CLASS @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public abstract class Persona { @Id private long id; private String rut; } @Entity @Table(name="PERSONA_NATURAL") public class PersonaNatural extends Persona { private String nombre; } @Entity @Table(name="PERSONA_JURIDICA") public class PersonaJuridica extends Persona { @Column(name="RAZON_SOCIAL") private String razonSocial; } 52 Uso de JPA n n La interfaz EntityManager es la fachada de JPA hacia el programador La anotación @PersistenceContext “inyecta” el Entity Manager @Stateless public class TestFacturasBean implements TestFacturas { @PersistenceContext private EntityManager em; public void creaFactura() { // creamos una factura y establecemos su data Factura factura = new Factura(); factura.setFecha(...); ... // agregamos lineas a la factura factura.addLinea("computadores", 10000000); factura.addLinea("impresoras", 600000); ... // grabamos la factura y las líneas en la base de datos em.persist(factura); } } 53 Operaciones sobre Entidades n El Entity Manager provee las siguiente operaciones: persist() Inserta una instancia en la base de datos remove() Elimina una instancia de la base de datos refresh() Recarga el estado de una instancia de la base de datos merge() Sincroniza el estado de una instancia “detached” con el contexto de persistencia find() Ejecuta un query por llave primaria createQuery() Crea una instancia de un query usando JPA QL dinámico createNamedQuery() Crea una instancia de un query predefinido createNativeQuery() Crea una instancia de un query a partir de una consulta SQL contains() Determina si una entidad pertenece a un contexto de persistencia flush() Fuerza la sincronización del contexto de persistencia con la base de datos 54 Queries n n n n n n n JPA provee un lenguaje de consultas llamado Java Persistence Query Language Soporta queries dinámicas y estáticas (named) Soporta binding de parámetros y paginación Similar a SQL, maneja agregaciones y funciones Soporta polimorfismo Estandariza el acceso a diferentes bases de datos Puede usar SQL List<Factura> findFacturasCliente(Long idCliente) { Query q = em.createQuery( "select f from Factura f where f.empresa.id = :idEmpresa order by f.fecha"); q.setParameter("idEmpresa", idEmpresa); q.setFirstResult(20); q.setMaxResults(10); return (List<Factura>) q.getResultList(); } 55 Funcionalidades Query Language n Inner joins n n Outer joins n n select o.id, sum(li.amount) from Order o join o.lineItems li group by o.id Funciones n n select o from Order o where exists( select li from o.lineItems li where li.amount > 100) Agregación n n select o from Order o left join o.lineItems li where li.amount > 100 Subselects n n select o from Order o join o.lineItems li where li.amount > 100 trim(), concat(), substring(), lower(), upper(), length(), abs(), sqrt(), mod(), size() Delete y update n n delete from Customer cust where cust.id = 12345 update OrderLine ol set ol.fulfilled = 'Y' where ol.order.id = 987654 56 DISCUSION / PREGUNTAS 57