<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
		<id>https://dosideas.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Barrios.nahuel</id>
		<title>Dos Ideas. - Contribuciones del usuario [es]</title>
		<link rel="self" type="application/atom+xml" href="https://dosideas.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Barrios.nahuel"/>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/Especial:Contribuciones/Barrios.nahuel"/>
		<updated>2026-06-10T02:59:04Z</updated>
		<subtitle>Contribuciones del usuario</subtitle>
		<generator>MediaWiki 1.28.2</generator>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Simple_XML&amp;diff=6760</id>
		<title>Simple XML</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Simple_XML&amp;diff=6760"/>
				<updated>2013-01-25T17:03:25Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Otro parser XML==&lt;br /&gt;
Ese es el punto. ¿Por qué otro des/serializador de XML &amp;gt; Java | Java &amp;gt; XML? Para conocer otra herramienta, con sus pros y contras, que en alguna situación pueda resultar ser una mejor opción que otro como [[XStream]], por ejemplo.&lt;br /&gt;
&lt;br /&gt;
Si siguen leyendo vamos a ver como agregar esta biblioteca utilitaria y unos ejemplos de uso básicos y muy sencillos.&lt;br /&gt;
&lt;br /&gt;
==Agregar dependencia==&lt;br /&gt;
Para agregar la dependencia, utilizando Maven, es suficiente con:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
     &amp;lt;groupId&amp;gt;org.simpleframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;
     &amp;lt;artifactId&amp;gt;simple-xml&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
     &amp;lt;version&amp;gt;2.6.9&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Se puede ver cuál es la última version disponible [http://mvnrepository.com/artifact/org.simpleframework/simple-xml desde acá]&lt;br /&gt;
&lt;br /&gt;
==La entidad==&lt;br /&gt;
&lt;br /&gt;
 import org.simpleframework.xml.Element;&lt;br /&gt;
&lt;br /&gt;
 public class Persona {&lt;br /&gt;
     @Element&lt;br /&gt;
     private String identidad;&lt;br /&gt;
     @Element&lt;br /&gt;
     private int edad;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Serializar (Java &amp;gt; XML)==&lt;br /&gt;
&lt;br /&gt;
===El método===&lt;br /&gt;
 public String obtenerXml(Persona persona) throws Exception {&lt;br /&gt;
     Serializer serializer = new Persister();&lt;br /&gt;
     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();&lt;br /&gt;
     serializer.write(persona, outputStream);&lt;br /&gt;
     return outputStream.toString();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* '''Nota''': El método write(), para la version de este ejemplo, se puede llamar con:&lt;br /&gt;
** java.io.File&lt;br /&gt;
** java.io.OutputStream&lt;br /&gt;
** java.io.Writer&lt;br /&gt;
** org.simpleframework.xml.stream.OutputNode&lt;br /&gt;
&lt;br /&gt;
===Resultado===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;persona&amp;gt;&lt;br /&gt;
    &amp;lt;identidad&amp;gt;34123456&amp;lt;/identidad&amp;gt;&lt;br /&gt;
    &amp;lt;edad&amp;gt;15&amp;lt;/edad&amp;gt;&lt;br /&gt;
 &amp;lt;/persona&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Deserializar (XML &amp;gt; Java)==&lt;br /&gt;
&lt;br /&gt;
===El método===&lt;br /&gt;
 public Persona crear(String xml) throws Exception {&lt;br /&gt;
     Serializer serializer = new Persister();&lt;br /&gt;
     return serializer.read(Persona.class, xml);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* '''Nota''': Vale mencionar que para deserializar un objeto es necesario que exista el constructor por default sin parámetros. De no hacerlo, lanzará una excepción:&lt;br /&gt;
&lt;br /&gt;
 org.simpleframework.xml.core.PersistenceException: Constructor not matched for class {miClase}&lt;br /&gt;
&lt;br /&gt;
==Alternativas para des/serialización de XML==&lt;br /&gt;
*XStream&lt;br /&gt;
** [[XStream | En esta wiki]].&lt;br /&gt;
** [http://xstream.codehaus.org/ Sitio web oficial].&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://simple.sourceforge.net/home.php Sitio web oficial de Simple XML Framework].&lt;br /&gt;
** [http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php Tutoriales desde el sitio oficial de Simple XML Framework]&lt;br /&gt;
** [http://simple.sourceforge.net/download/stream/doc/examples/examples.php Ejemplos más complejos desde el sitio oficial de Simple XML Framework]&lt;br /&gt;
* Proyecto de ejemplo (el código de este tutorial, con ejemplos funcionando más complejos):&lt;br /&gt;
** SVN: http://dosideas-aplicaciones-modelo.googlecode.com/svn/test-simpleXmlFramework&lt;br /&gt;
** Web: http://code.google.com/p/dosideas-aplicaciones-modelo/source/browse/#svn%2Ftest-simpleXmlFramework&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Simple_XML&amp;diff=6759</id>
		<title>Simple XML</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Simple_XML&amp;diff=6759"/>
				<updated>2013-01-25T17:02:42Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: /* La entidad */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Otro parser XML==&lt;br /&gt;
Ese es el punto. ¿Por qué otro des/serializador de XML &amp;gt; Java | Java &amp;gt; XML? Para conocer otra herramienta, con sus pros y contras, que en alguna situación pueda resultar ser una mejor opción que otro como [[XStream]], por ejemplo.&lt;br /&gt;
&lt;br /&gt;
Si siguen leyendo vamos a ver como agregar esta biblioteca utilitaria y unos ejemplos de uso básicos y muy sencillos.&lt;br /&gt;
&lt;br /&gt;
==Agregar dependencia==&lt;br /&gt;
Para agregar la dependencia, utilizando Maven, es suficiente con:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
     &amp;lt;groupId&amp;gt;org.simpleframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;
     &amp;lt;artifactId&amp;gt;simple-xml&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
     &amp;lt;version&amp;gt;2.6.9&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Se puede ver cuál es la última version disponible [http://mvnrepository.com/artifact/org.simpleframework/simple-xml desde acá]&lt;br /&gt;
&lt;br /&gt;
==La entidad==&lt;br /&gt;
&lt;br /&gt;
 import org.simpleframework.xml.Element;&lt;br /&gt;
&lt;br /&gt;
 public class Persona {&lt;br /&gt;
     @Element&lt;br /&gt;
     private String identidad;&lt;br /&gt;
     @Element&lt;br /&gt;
     private int edad;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Serializar (Java &amp;gt; XML)==&lt;br /&gt;
&lt;br /&gt;
===El método===&lt;br /&gt;
 public String obtenerXml(Persona persona) throws Exception {&lt;br /&gt;
     Serializer serializer = new Persister();&lt;br /&gt;
     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();&lt;br /&gt;
     serializer.write(persona, outputStream);&lt;br /&gt;
     return outputStream.toString();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* '''Nota''': El método write(), para la version de este ejemplo, se puede llamar con:&lt;br /&gt;
** java.io.File&lt;br /&gt;
** java.io.OutputStream&lt;br /&gt;
** java.io.Writer&lt;br /&gt;
** org.simpleframework.xml.stream.OutputNode&lt;br /&gt;
&lt;br /&gt;
===Resultado===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;persona&amp;gt;&lt;br /&gt;
    &amp;lt;identidad&amp;gt;34123456&amp;lt;/identidad&amp;gt;&lt;br /&gt;
    &amp;lt;edad&amp;gt;15&amp;lt;/edad&amp;gt;&lt;br /&gt;
 &amp;lt;/persona&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Deserializar (XML &amp;gt; Java)==&lt;br /&gt;
&lt;br /&gt;
===El método===&lt;br /&gt;
 public Persona crear(String xml) throws Exception {&lt;br /&gt;
     Serializer serializer = new Persister();&lt;br /&gt;
     return serializer.read(Persona.class, xml);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* '''Nota''': Vale mencionar que para deserializar un objeto es necesario que exista el constructor por default sin parámetros. De no hacerlo, lanzará una excepción:&lt;br /&gt;
&lt;br /&gt;
 org.simpleframework.xml.core.PersistenceException: Constructor not matched for class {miClase}&lt;br /&gt;
&lt;br /&gt;
==Alternativas para des/serialización de XML==&lt;br /&gt;
*XStream&lt;br /&gt;
** [[XStream | En esta wiki]].&lt;br /&gt;
** [http://xstream.codehaus.org/ Sitio web oficial].&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://simple.sourceforge.net/home.php Sitio web oficial de Simple XML Framework].&lt;br /&gt;
** [http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php Tutoriales desde el sitio oficial de Simple XML Framework]&lt;br /&gt;
** [http://simple.sourceforge.net/download/stream/doc/examples/examples.php Ejemplos más complejos desde el sitio oficial de Simple XML Framework]&lt;br /&gt;
* Proyecto de ejemplo (el código de este tutorial):&lt;br /&gt;
** SVN: http://dosideas-aplicaciones-modelo.googlecode.com/svn/test-simpleXmlFramework&lt;br /&gt;
** Web: http://code.google.com/p/dosideas-aplicaciones-modelo/source/browse/#svn%2Ftest-simpleXmlFramework&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Simple_XML&amp;diff=6758</id>
		<title>Simple XML</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Simple_XML&amp;diff=6758"/>
				<updated>2013-01-22T19:50:39Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: Agrego la URL del repositorio en Google Code para el proyecto que agregue de Simple XML&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Otro parser XML==&lt;br /&gt;
Ese es el punto. ¿Por qué otro des/serializador de XML &amp;gt; Java | Java &amp;gt; XML? Para conocer otra herramienta, con sus pros y contras, que en alguna situación pueda resultar ser una mejor opción que otro como [[XStream]], por ejemplo.&lt;br /&gt;
&lt;br /&gt;
Si siguen leyendo vamos a ver como agregar esta biblioteca utilitaria y unos ejemplos de uso básicos y muy sencillos.&lt;br /&gt;
&lt;br /&gt;
==Agregar dependencia==&lt;br /&gt;
Para agregar la dependencia, utilizando Maven, es suficiente con:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
     &amp;lt;groupId&amp;gt;org.simpleframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;
     &amp;lt;artifactId&amp;gt;simple-xml&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
     &amp;lt;version&amp;gt;2.6.9&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Se puede ver cuál es la última version disponible [http://mvnrepository.com/artifact/org.simpleframework/simple-xml desde acá]&lt;br /&gt;
&lt;br /&gt;
==La entidad==&lt;br /&gt;
&lt;br /&gt;
 import org.simpleframework.xml.Element;&lt;br /&gt;
 import org.simpleframework.xml.Root;&lt;br /&gt;
&lt;br /&gt;
 @Root&lt;br /&gt;
 public class Persona {&lt;br /&gt;
     @Element&lt;br /&gt;
     private String identidad;&lt;br /&gt;
     @Element&lt;br /&gt;
     private int edad;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Serializar (Java &amp;gt; XML)==&lt;br /&gt;
&lt;br /&gt;
===El método===&lt;br /&gt;
 public String obtenerXml(Persona persona) throws Exception {&lt;br /&gt;
     Serializer serializer = new Persister();&lt;br /&gt;
     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();&lt;br /&gt;
     serializer.write(persona, outputStream);&lt;br /&gt;
     return outputStream.toString();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* '''Nota''': El método write(), para la version de este ejemplo, se puede llamar con:&lt;br /&gt;
** java.io.File&lt;br /&gt;
** java.io.OutputStream&lt;br /&gt;
** java.io.Writer&lt;br /&gt;
** org.simpleframework.xml.stream.OutputNode&lt;br /&gt;
&lt;br /&gt;
===Resultado===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;persona&amp;gt;&lt;br /&gt;
    &amp;lt;identidad&amp;gt;34123456&amp;lt;/identidad&amp;gt;&lt;br /&gt;
    &amp;lt;edad&amp;gt;15&amp;lt;/edad&amp;gt;&lt;br /&gt;
 &amp;lt;/persona&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Deserializar (XML &amp;gt; Java)==&lt;br /&gt;
&lt;br /&gt;
===El método===&lt;br /&gt;
 public Persona crear(String xml) throws Exception {&lt;br /&gt;
     Serializer serializer = new Persister();&lt;br /&gt;
     return serializer.read(Persona.class, xml);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* '''Nota''': Vale mencionar que para deserializar un objeto es necesario que exista el constructor por default sin parámetros. De no hacerlo, lanzará una excepción:&lt;br /&gt;
&lt;br /&gt;
 org.simpleframework.xml.core.PersistenceException: Constructor not matched for class {miClase}&lt;br /&gt;
&lt;br /&gt;
==Alternativas para des/serialización de XML==&lt;br /&gt;
*XStream&lt;br /&gt;
** [[XStream | En esta wiki]].&lt;br /&gt;
** [http://xstream.codehaus.org/ Sitio web oficial].&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://simple.sourceforge.net/home.php Sitio web oficial de Simple XML Framework].&lt;br /&gt;
** [http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php Tutoriales desde el sitio oficial de Simple XML Framework]&lt;br /&gt;
** [http://simple.sourceforge.net/download/stream/doc/examples/examples.php Ejemplos más complejos desde el sitio oficial de Simple XML Framework]&lt;br /&gt;
* Proyecto de ejemplo (el código de este tutorial):&lt;br /&gt;
** SVN: http://dosideas-aplicaciones-modelo.googlecode.com/svn/test-simpleXmlFramework&lt;br /&gt;
** Web: http://code.google.com/p/dosideas-aplicaciones-modelo/source/browse/#svn%2Ftest-simpleXmlFramework&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Simple_XML&amp;diff=6757</id>
		<title>Simple XML</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Simple_XML&amp;diff=6757"/>
				<updated>2013-01-22T19:33:40Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: Creo una página nueva en la Wiki sobre Simple XML (framework para des/serializacion de XML)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Otro parser XML==&lt;br /&gt;
Ese es el punto. ¿Por qué otro des/serializador de XML &amp;gt; Java | Java &amp;gt; XML? Para conocer otra herramienta, con sus pros y contras, que en alguna situación pueda resultar ser una mejor opción que otro como [[XStream]], por ejemplo.&lt;br /&gt;
&lt;br /&gt;
Si siguen leyendo vamos a ver como agregar esta biblioteca utilitaria y unos ejemplos de uso básicos y muy sencillos.&lt;br /&gt;
&lt;br /&gt;
==Agregar dependencia==&lt;br /&gt;
Para agregar la dependencia, utilizando Maven, es suficiente con:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
     &amp;lt;groupId&amp;gt;org.simpleframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;
     &amp;lt;artifactId&amp;gt;simple-xml&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
     &amp;lt;version&amp;gt;2.6.9&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Se puede ver cuál es la última version disponible [http://mvnrepository.com/artifact/org.simpleframework/simple-xml desde acá]&lt;br /&gt;
&lt;br /&gt;
==La entidad==&lt;br /&gt;
&lt;br /&gt;
 import org.simpleframework.xml.Element;&lt;br /&gt;
 import org.simpleframework.xml.Root;&lt;br /&gt;
&lt;br /&gt;
 @Root&lt;br /&gt;
 public class Persona {&lt;br /&gt;
     @Element&lt;br /&gt;
     private String identidad;&lt;br /&gt;
     @Element&lt;br /&gt;
     private int edad;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Serializar (Java &amp;gt; XML)==&lt;br /&gt;
&lt;br /&gt;
===El método===&lt;br /&gt;
 public String obtenerXml(Persona persona) throws Exception {&lt;br /&gt;
     Serializer serializer = new Persister();&lt;br /&gt;
     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();&lt;br /&gt;
     serializer.write(persona, outputStream);&lt;br /&gt;
     return outputStream.toString();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* '''Nota''': El método write(), para la version de este ejemplo, se puede llamar con:&lt;br /&gt;
** java.io.File&lt;br /&gt;
** java.io.OutputStream&lt;br /&gt;
** java.io.Writer&lt;br /&gt;
** org.simpleframework.xml.stream.OutputNode&lt;br /&gt;
&lt;br /&gt;
===Resultado===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;persona&amp;gt;&lt;br /&gt;
    &amp;lt;identidad&amp;gt;34123456&amp;lt;/identidad&amp;gt;&lt;br /&gt;
    &amp;lt;edad&amp;gt;15&amp;lt;/edad&amp;gt;&lt;br /&gt;
 &amp;lt;/persona&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Deserializar (XML &amp;gt; Java)==&lt;br /&gt;
&lt;br /&gt;
===El método===&lt;br /&gt;
 public Persona crear(String xml) throws Exception {&lt;br /&gt;
     Serializer serializer = new Persister();&lt;br /&gt;
     return serializer.read(Persona.class, xml);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* '''Nota''': Vale mencionar que para deserializar un objeto es necesario que exista el constructor por default sin parámetros. De no hacerlo, lanzará una excepción:&lt;br /&gt;
&lt;br /&gt;
 org.simpleframework.xml.core.PersistenceException: Constructor not matched for class {miClase}&lt;br /&gt;
&lt;br /&gt;
==Alternativas para des/serialización de XML==&lt;br /&gt;
*XStream&lt;br /&gt;
** [[XStream | En esta wiki]].&lt;br /&gt;
** [http://xstream.codehaus.org/ Sitio web oficial].&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://simple.sourceforge.net/home.php Sitio web oficial de Simple XML Framework].&lt;br /&gt;
** [http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php Tutoriales desde el sitio oficial de Simple XML Framework]&lt;br /&gt;
** [http://simple.sourceforge.net/download/stream/doc/examples/examples.php Ejemplos más complejos desde el sitio oficial de Simple XML Framework]&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Desarrollando_Android_apps_para_distintas_pantallas&amp;diff=6710</id>
		<title>Desarrollando Android apps para distintas pantallas</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Desarrollando_Android_apps_para_distintas_pantallas&amp;diff=6710"/>
				<updated>2012-10-02T14:41:17Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: Desarrollando Android apps para distintas pantallas&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Términos y conceptos principales=&lt;br /&gt;
&lt;br /&gt;
* Tamaño de la pantalla: El tamaño físico real de la pantalla medido diagonalmente.&lt;br /&gt;
* Densidad de la pantalla: Cantidad de píxels en una pulgada cuadrada de la pantalla. Dots per inch (dip).&lt;br /&gt;
* Orientación: Vertical/Horizontal (land/port)&lt;br /&gt;
* Resolución: La cantidad total de píxels que tiene la pantalla.&lt;br /&gt;
* Píxel independiente de la densidad (dp):&lt;br /&gt;
* Nomenclaturas: De las siguientes generalizaciones, se toma el tamaño normal, y la densidad medium como la estándar.&lt;br /&gt;
&lt;br /&gt;
=Unidades disponibles=&lt;br /&gt;
&lt;br /&gt;
==Dependientes del tamaño de la pantalla==&lt;br /&gt;
&lt;br /&gt;
* Pulgadas (in)&lt;br /&gt;
* Puntos (pt): Un punto vale 1/72 de una pulgada.&lt;br /&gt;
* Milímetros (mm)&lt;br /&gt;
&lt;br /&gt;
==Independientes del tamaño de la pantalla==&lt;br /&gt;
&lt;br /&gt;
* Pixels (px): No se recomienda utilizar píxels porque la cantidad de píxels por pulgada varía entre distintos dispositivos.&lt;br /&gt;
&lt;br /&gt;
* Density-independent pixels (dp): Es una unidad de medida virtual, que está basada en la densidad de la pantalla. Es relativa a una pantalla de tamaño normal y densidad mdpi como ya vimos más arriba que es el estándar. Al usar esta medida estamos permitiendo que el Sistema Operativo se encargue de redimensionar los elementos de la GUI de acuerdo a cada dispositivo, por lo tanto es aconsejable utilizar siempre esta unidad de medida.&lt;br /&gt;
&lt;br /&gt;
* Scale-independent pixels (sp): Son como los dp, pero además están vinculados (escalados) al tamaño de la fuente que el usuario tiene asignada en el resto del dispositivo. Se debe usar esta unidad de medida siempre que se esté definiendo el tamaño de algún texto que se muestre en la GUI.&lt;br /&gt;
&lt;br /&gt;
=Entendiendo cómo funciona=&lt;br /&gt;
&lt;br /&gt;
El Sistema Operativo se encarga de agrupar los distintos tamaños de pantallas, para ello, cada una de las agrupaciones, tanto de tamaño como densidad abarca un rango finito de medidas. De esta manera, a una pantalla de 2 pulgadas, le corresponde el tamaño “small” y si la densidad es 180 le corresponderá “mdpi”.&lt;br /&gt;
&lt;br /&gt;
=Alternativas para soportar múltiples pantallas=&lt;br /&gt;
&lt;br /&gt;
* Explícitamente declarando en el Manifest.xml&lt;br /&gt;
&lt;br /&gt;
En el archivo de manifiesto se puede especificar explícitamente para qué tamaños de pantallas se podrá instalar la aplicación. Es decír, aquellos dispositivos que no cumplan con esa especificación directamente no podrán instalar la aplicación.&lt;br /&gt;
&lt;br /&gt;
* Distintos layouts para distintas pantallas&lt;br /&gt;
&lt;br /&gt;
Si bien el sistema operativo redimensiona los layouts de acuerdo al tipo de pantalla de cada dispositivo, y esto en la mayoría de los casos hace que la aplicación se vea bien, una solución es crear el mismo layout para cada tipo de pantalla.&lt;br /&gt;
&lt;br /&gt;
* Utilizar unidades de medidas escalables por el Sistema Operativo&lt;br /&gt;
&lt;br /&gt;
Esto es tán simple como empezar a hacer las cosas bien desde un primer instante, y nuestra aplicación quedará lista para ser compatible con cualquier pantalla. Se trata de utilizar las siguientes unidades para determinadas situaciones:&lt;br /&gt;
&lt;br /&gt;
Para indicar cualquier tamaño de widgets, o distancia entre ellos, hay que utilizar la unidad “dp” (y no “px” como naturalmente haríamos).&lt;br /&gt;
Cuando se indique el tamaño de las fuentes, hay que usar “sp” debido a que esta unidad está vinculada con el tamaño de fuente especificado por el usuario a todo el SO, entonces se adaptaría a las preferencias del usuario.&lt;br /&gt;
&lt;br /&gt;
* Proveer distintos recursos para cada tipo de pantalla.&lt;br /&gt;
&lt;br /&gt;
El Sistema Operativo escalará todos los recursos (como las imágenes) de acuerdo al tipo de pantalla de cada dispositivo para que se vean correctamente. Sin embargo, es conveniente proveer un recurso con el tamaño adecuado para tipo de pantalla.&lt;br /&gt;
&lt;br /&gt;
=¿Cómo testear la compatibilidad?=&lt;br /&gt;
&lt;br /&gt;
Para probar que la aplicación se ve correctamente en distintos dispositivos con distintas características de pantallas, se debe crear un emulador distinto para cada tipo de pantalla que se quiera probar, y luego verificar visualmente todas las actividades de la aplicación.&lt;br /&gt;
&lt;br /&gt;
===Fuente===&lt;br /&gt;
* [http://developer.android.com/develop/index.html Sitio web de Android para desarrolladores]&lt;br /&gt;
&lt;br /&gt;
===Ver también===&lt;br /&gt;
* [https://docs.google.com/document/d/1foAIFGOm9UsUMl5ebdDEWvrtAAQO0kHHyqvHtwB_N-A/edit Desarrollando Android apps para distintas pantallas (actualizado)]&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6627</id>
		<title>Spring Data</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6627"/>
				<updated>2012-06-15T15:50:37Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: /* Comentario adicional */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introducción==&lt;br /&gt;
La herramienta que encontramos útil para dejar de hacer manualmente las implementaciones de los DAO que suelen ser siempre de la misma manera, fué a través de Spring Data JPA. [http://www.springsource.org/spring-data/jpa|http://www.springsource.org/spring-data/jpa]&lt;br /&gt;
&lt;br /&gt;
Este framework nos permite, siguiendo una serie de normas que nos establece, crear interfaces de DAOs definiendo métodos y NO realizar ninguna implementación. Es decir, dejamos la responsabilidad de la implementación al framework, el cuál hará la implementación en tiempo de corrida.&lt;br /&gt;
Para ello, el framework básicamente lo que hace es buscar, dado un paquete que le indicamos por configuración, todas las interfaces que hereden de org.springframework.data.repository.Repository&amp;lt;T, ID extends Serializable&amp;gt; ya sea directa o indirectamente.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Spring-Data-JPA-Herencia repository.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Configuración==&lt;br /&gt;
&lt;br /&gt;
===Dependencias (Utilizando Maven)===&lt;br /&gt;
Para trabajar con Spring Data JPA, solo debemos agregar la dependencia:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
      &amp;lt;groupId&amp;gt;org.springframework.data&amp;lt;/groupId&amp;gt;&lt;br /&gt;
      &amp;lt;artifactId&amp;gt;spring-data-jpa&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
      &amp;lt;version&amp;gt;1.0.3.RELEASE&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siempre y cuando contemos con una configuración de persistencia que utilice:&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.orm.jpa.JpaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;entityManagerFactory&amp;quot; ref=&amp;quot;entityManagerFactory&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaDialect&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaDialect&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/bean&amp;gt;&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;entityManagerFactory&amp;quot; class=&amp;quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;defaultDataSource&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;property name=&amp;quot;generateDdl&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
           &amp;lt;/bean&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configurando el paquete a escanear===&lt;br /&gt;
&lt;br /&gt;
En el applicationContext.xml:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:jpa=&amp;quot;http://www.springframework.org/schema/data/jpa&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;br /&gt;
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    &amp;lt;!-- Declara los repositorios de datos. Se implementarán automáticamente todas&lt;br /&gt;
         las interfaces que hereden de Repository (o CrudRepository).&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;jpa:repositories base-package=&amp;quot;com.th.ctc.dao&amp;quot; /&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
 &amp;lt;/beans&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementación==&lt;br /&gt;
===El ejemplo fácil===&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.CrudRepository;&lt;br /&gt;
 import com.th.ctc.domain.Cliente;&lt;br /&gt;
 /**&lt;br /&gt;
  * Interfaz del DAO para la entidad {@link Cliente}. Esta interfaz NO tiene una&lt;br /&gt;
  * implementacion concreta dado que al extender de Repository la implementacion&lt;br /&gt;
  * la hace en runtime Spring Data JPA.&lt;br /&gt;
  * &lt;br /&gt;
  * @author Alguien.&lt;br /&gt;
  */&lt;br /&gt;
 public interface ClienteDao extends CrudRepository&amp;lt;Cliente, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de clientes.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private ClienteDao clienteDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Cliente&amp;gt; buscarTodos() {&lt;br /&gt;
      return (List&amp;lt;Cliente&amp;gt;) clienteDao.findAll(); //El método findAll() proviene de CrudRepository&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===El ejemplo habitual===&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Usuario;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz del DAO para la entidad {@link Usuario}. Esta interfaz NO tiene una&lt;br /&gt;
 * implementacion concreta dado que al extender de Repository la implementación&lt;br /&gt;
 * la hace en runtime Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface UsuarioDao extends PagingAndSortingRepository&amp;lt;Usuario, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de usuarios.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private UsuarioDao usuarioDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Usuario&amp;gt; buscarTodos() {&lt;br /&gt;
      // El método findAll(Sort) proviene de PagingAndSortingRepository y con el String &amp;quot;apellido&amp;quot; (es el nombre del &lt;br /&gt;
      // atributo de clase de la entidad Usuario) estamos indicando que se ordenaran los resultados por ese campo&lt;br /&gt;
      return (List&amp;lt;Usuario&amp;gt;) usuarioDao.findAll(new Sort(&amp;quot;apellido&amp;quot;)); &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
===El ejemplo dificil===&lt;br /&gt;
Supongamos que ahora necesitamos 2 cosas:&lt;br /&gt;
Por un lado, recuperar todos los elementos de una entidad, recuperar uno solo en base al ID y etc., y por otro, generar un archivo Excel con información recuperada de una consulta a una base de datos muy específica.&lt;br /&gt;
Para lograr esto, aprovechando esta herramienta, necesitamos 2 interfaces del DAO. Una para definir estos métodos tan complejos que necesitamos, y otra para utilizar de la misma manera que en el ejemplo fácil.&lt;br /&gt;
&lt;br /&gt;
¿Pero entonces el Service tiene que utilizar 2 DAOs distintos sobre la misma entidad?&lt;br /&gt;
&lt;br /&gt;
No. Antes que nada, veamos un diagrama de clases para que veamos por qué este es el ejemplo dificil:&lt;br /&gt;
[[Media:Ejemplo complejo Spring Data JPA.PNG|Diagrama de clases]]&lt;br /&gt;
&lt;br /&gt;
Es decir, tenemos un Service (TareaServiceImpl) que utiliza un DAO (TareaDao). Nada nuevo hasta acá. Sin embargo, este TareaDao no solo hereda de Repository al heredar de org.springframework.data.repository.PagingAndSortingRepository, sino que también está heredando de una interfaz definida por nosotros (CustomTareaDao).&lt;br /&gt;
&lt;br /&gt;
¿Por qué necesitamos esto?&lt;br /&gt;
&lt;br /&gt;
Bueno, por que si bien podemos definir métodos en la interfaz que hereda de Repository, estos métodos tienen que seguir una nomenclatura específica para que el framework pueda hacer la implementación y, además, porque no podemos definir métodos que no queremos que los implemente Spring Data JPA para implementarlos nosotros.&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
&lt;br /&gt;
 import java.util.Date;&lt;br /&gt;
 import java.util.List;&lt;br /&gt;
 import org.springframework.data.domain.Sort;&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Tarea;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz el DAO de las {@link Tarea} implementado por Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface TareaDao extends PagingAndSortingRepository&amp;lt;Tarea, Long&amp;gt;, CustomTareaDao {&lt;br /&gt;
    /**&lt;br /&gt;
     * Recupera todas las tareas del usuario que le pasamos, para la fecha dada.&lt;br /&gt;
     * &lt;br /&gt;
     * @author Alguien.&lt;br /&gt;
     * @param idUsuario&lt;br /&gt;
     *            {@link Long} con el ID del usuario duenio de la tarea.&lt;br /&gt;
     * @param fechaDesde&lt;br /&gt;
     *            {@link Date} la fecha desde la cual se buscara.&lt;br /&gt;
     * @param fechaHasta&lt;br /&gt;
     *            {@link Date} la fecha hasta la cual se buscara.&lt;br /&gt;
     * @param sort&lt;br /&gt;
     *            {@link Sort} de Spring Data JPA utilizado para ordenar los&lt;br /&gt;
     *            resultados segun cierto criterio.&lt;br /&gt;
     * @return {@link List&amp;lt;Tarea&amp;gt;} Las tareas encontradas.&lt;br /&gt;
     */&lt;br /&gt;
    List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Como vemos, estamos definiendo un método '''findByUsuarioIdAndFechaBetween''' que sigue la nomenclatura del framework para recuperar un listado de tareas en base al Id del Usuario que le pasamos, entre un rango de fechas dado, y que al definir con esta nomenclatura hacemos que la implementación quede a cargo del framework.&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Ahora, nuestro Service cuenta con un DAO que tiene:&lt;br /&gt;
* Métodos definidos en él;&lt;br /&gt;
* Métodos provistos por PagingAndSortingRepository;&lt;br /&gt;
* Métodos provistos por CustomTareaDao. &lt;br /&gt;
&lt;br /&gt;
¿Y las implementaciones?&lt;br /&gt;
&lt;br /&gt;
Las implementaciones de los métodos definidos en TareaDao y los heredados de PagingAndSortingRepository, nos las va a proveer el framework. Y para la interfaz CustomTareaDao nosotros debemos definir nuestro DaoImpl común y corriente.&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
A la hora de testear, debemos tener un test (en nuestro caso es TareaDaoComponenteTest) que testee de la interfaz DAO que exponemos (es decír, TareaDao): &lt;br /&gt;
* Los métodos definidos manualmente en el DAO siguiendo la nomenclatura específica del framework. Ej: List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
* Los métodos definidos en la interfaz creada para los métodos específicos (CustomTareaDao). Ej: ScrollableResults buscarResumenHoras(FiltroResumenHorasDto filtro);&lt;br /&gt;
&lt;br /&gt;
===Test===&lt;br /&gt;
Como estamos delegando la responsabilidad de la implementación del DAO en un framework, y como ni siquiera sabemos como es la implementación dado que se produce en runtime, decidimos no testear aquellos métodos ya tenemos definidos al heredar de alguna de las interfaces que nos provee la herramienta.&lt;br /&gt;
Sin embargo, sí decidimos testear la capa del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA, además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
==Mas==&lt;br /&gt;
&lt;br /&gt;
===SELECT DISTINCT===&lt;br /&gt;
&lt;br /&gt;
====Situación a resolver====&lt;br /&gt;
Necesitamos recuperar todos los clientes, tal que alguno de los servicios de los clientes cumpla con una condición determinada.&lt;br /&gt;
&lt;br /&gt;
====Primera solución====&lt;br /&gt;
Creamos un método:&lt;br /&gt;
 List&amp;lt;Cliente&amp;gt; findByServiciosEstado(EstadosServicios estado);&lt;br /&gt;
&lt;br /&gt;
====Problema====&lt;br /&gt;
El método traía repetidos los clientes por cada uno de sus servicios que cumplían con la condición.&lt;br /&gt;
&lt;br /&gt;
=====Contexto=====&lt;br /&gt;
* Spring Data JPA, version 1.0.3.RELEASE.&lt;br /&gt;
&lt;br /&gt;
=====Solución=====&lt;br /&gt;
Al método le agregamos la keyword Distinct delante del By:&lt;br /&gt;
  List&amp;lt;Cliente&amp;gt; findDistinctByServiciosEstado(EstadosServicios estado);&lt;br /&gt;
&lt;br /&gt;
=====Comentario adicional=====&lt;br /&gt;
El problema de esto es que la keyword no está en la [http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/#repository-query-keywords| documentación oficial de Spring Data JPA].&lt;br /&gt;
Sin embargo, encontramos una [https://jira.springsource.org/browse/DATAJPA-174?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab| issue en el Jira de Spring Data JPA] sobre el tema.&lt;br /&gt;
&lt;br /&gt;
Por último, [http://static.springsource.org/spring-data/data-jpa/docs/1.0.0.RELEASE/changelog.txt | en el changelog de la versión] se indica que está soportado.&lt;br /&gt;
&lt;br /&gt;
===Proyecto de ejemplo===&lt;br /&gt;
Pueden descargarse un proyecto de ejemplo haciendo un checkout mediante un cliente de SVN de:&lt;br /&gt;
 http://dosideas-aplicaciones-modelo.googlecode.com/svn/trunk/spring-data/trunk&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6626</id>
		<title>Spring Data</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6626"/>
				<updated>2012-06-15T15:48:10Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: /* Mas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introducción==&lt;br /&gt;
La herramienta que encontramos útil para dejar de hacer manualmente las implementaciones de los DAO que suelen ser siempre de la misma manera, fué a través de Spring Data JPA. [http://www.springsource.org/spring-data/jpa|http://www.springsource.org/spring-data/jpa]&lt;br /&gt;
&lt;br /&gt;
Este framework nos permite, siguiendo una serie de normas que nos establece, crear interfaces de DAOs definiendo métodos y NO realizar ninguna implementación. Es decir, dejamos la responsabilidad de la implementación al framework, el cuál hará la implementación en tiempo de corrida.&lt;br /&gt;
Para ello, el framework básicamente lo que hace es buscar, dado un paquete que le indicamos por configuración, todas las interfaces que hereden de org.springframework.data.repository.Repository&amp;lt;T, ID extends Serializable&amp;gt; ya sea directa o indirectamente.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Spring-Data-JPA-Herencia repository.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Configuración==&lt;br /&gt;
&lt;br /&gt;
===Dependencias (Utilizando Maven)===&lt;br /&gt;
Para trabajar con Spring Data JPA, solo debemos agregar la dependencia:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
      &amp;lt;groupId&amp;gt;org.springframework.data&amp;lt;/groupId&amp;gt;&lt;br /&gt;
      &amp;lt;artifactId&amp;gt;spring-data-jpa&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
      &amp;lt;version&amp;gt;1.0.3.RELEASE&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siempre y cuando contemos con una configuración de persistencia que utilice:&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.orm.jpa.JpaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;entityManagerFactory&amp;quot; ref=&amp;quot;entityManagerFactory&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaDialect&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaDialect&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/bean&amp;gt;&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;entityManagerFactory&amp;quot; class=&amp;quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;defaultDataSource&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;property name=&amp;quot;generateDdl&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
           &amp;lt;/bean&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configurando el paquete a escanear===&lt;br /&gt;
&lt;br /&gt;
En el applicationContext.xml:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:jpa=&amp;quot;http://www.springframework.org/schema/data/jpa&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;br /&gt;
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    &amp;lt;!-- Declara los repositorios de datos. Se implementarán automáticamente todas&lt;br /&gt;
         las interfaces que hereden de Repository (o CrudRepository).&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;jpa:repositories base-package=&amp;quot;com.th.ctc.dao&amp;quot; /&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
 &amp;lt;/beans&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementación==&lt;br /&gt;
===El ejemplo fácil===&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.CrudRepository;&lt;br /&gt;
 import com.th.ctc.domain.Cliente;&lt;br /&gt;
 /**&lt;br /&gt;
  * Interfaz del DAO para la entidad {@link Cliente}. Esta interfaz NO tiene una&lt;br /&gt;
  * implementacion concreta dado que al extender de Repository la implementacion&lt;br /&gt;
  * la hace en runtime Spring Data JPA.&lt;br /&gt;
  * &lt;br /&gt;
  * @author Alguien.&lt;br /&gt;
  */&lt;br /&gt;
 public interface ClienteDao extends CrudRepository&amp;lt;Cliente, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de clientes.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private ClienteDao clienteDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Cliente&amp;gt; buscarTodos() {&lt;br /&gt;
      return (List&amp;lt;Cliente&amp;gt;) clienteDao.findAll(); //El método findAll() proviene de CrudRepository&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===El ejemplo habitual===&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Usuario;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz del DAO para la entidad {@link Usuario}. Esta interfaz NO tiene una&lt;br /&gt;
 * implementacion concreta dado que al extender de Repository la implementación&lt;br /&gt;
 * la hace en runtime Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface UsuarioDao extends PagingAndSortingRepository&amp;lt;Usuario, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de usuarios.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private UsuarioDao usuarioDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Usuario&amp;gt; buscarTodos() {&lt;br /&gt;
      // El método findAll(Sort) proviene de PagingAndSortingRepository y con el String &amp;quot;apellido&amp;quot; (es el nombre del &lt;br /&gt;
      // atributo de clase de la entidad Usuario) estamos indicando que se ordenaran los resultados por ese campo&lt;br /&gt;
      return (List&amp;lt;Usuario&amp;gt;) usuarioDao.findAll(new Sort(&amp;quot;apellido&amp;quot;)); &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
===El ejemplo dificil===&lt;br /&gt;
Supongamos que ahora necesitamos 2 cosas:&lt;br /&gt;
Por un lado, recuperar todos los elementos de una entidad, recuperar uno solo en base al ID y etc., y por otro, generar un archivo Excel con información recuperada de una consulta a una base de datos muy específica.&lt;br /&gt;
Para lograr esto, aprovechando esta herramienta, necesitamos 2 interfaces del DAO. Una para definir estos métodos tan complejos que necesitamos, y otra para utilizar de la misma manera que en el ejemplo fácil.&lt;br /&gt;
&lt;br /&gt;
¿Pero entonces el Service tiene que utilizar 2 DAOs distintos sobre la misma entidad?&lt;br /&gt;
&lt;br /&gt;
No. Antes que nada, veamos un diagrama de clases para que veamos por qué este es el ejemplo dificil:&lt;br /&gt;
[[Media:Ejemplo complejo Spring Data JPA.PNG|Diagrama de clases]]&lt;br /&gt;
&lt;br /&gt;
Es decir, tenemos un Service (TareaServiceImpl) que utiliza un DAO (TareaDao). Nada nuevo hasta acá. Sin embargo, este TareaDao no solo hereda de Repository al heredar de org.springframework.data.repository.PagingAndSortingRepository, sino que también está heredando de una interfaz definida por nosotros (CustomTareaDao).&lt;br /&gt;
&lt;br /&gt;
¿Por qué necesitamos esto?&lt;br /&gt;
&lt;br /&gt;
Bueno, por que si bien podemos definir métodos en la interfaz que hereda de Repository, estos métodos tienen que seguir una nomenclatura específica para que el framework pueda hacer la implementación y, además, porque no podemos definir métodos que no queremos que los implemente Spring Data JPA para implementarlos nosotros.&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
&lt;br /&gt;
 import java.util.Date;&lt;br /&gt;
 import java.util.List;&lt;br /&gt;
 import org.springframework.data.domain.Sort;&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Tarea;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz el DAO de las {@link Tarea} implementado por Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface TareaDao extends PagingAndSortingRepository&amp;lt;Tarea, Long&amp;gt;, CustomTareaDao {&lt;br /&gt;
    /**&lt;br /&gt;
     * Recupera todas las tareas del usuario que le pasamos, para la fecha dada.&lt;br /&gt;
     * &lt;br /&gt;
     * @author Alguien.&lt;br /&gt;
     * @param idUsuario&lt;br /&gt;
     *            {@link Long} con el ID del usuario duenio de la tarea.&lt;br /&gt;
     * @param fechaDesde&lt;br /&gt;
     *            {@link Date} la fecha desde la cual se buscara.&lt;br /&gt;
     * @param fechaHasta&lt;br /&gt;
     *            {@link Date} la fecha hasta la cual se buscara.&lt;br /&gt;
     * @param sort&lt;br /&gt;
     *            {@link Sort} de Spring Data JPA utilizado para ordenar los&lt;br /&gt;
     *            resultados segun cierto criterio.&lt;br /&gt;
     * @return {@link List&amp;lt;Tarea&amp;gt;} Las tareas encontradas.&lt;br /&gt;
     */&lt;br /&gt;
    List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Como vemos, estamos definiendo un método '''findByUsuarioIdAndFechaBetween''' que sigue la nomenclatura del framework para recuperar un listado de tareas en base al Id del Usuario que le pasamos, entre un rango de fechas dado, y que al definir con esta nomenclatura hacemos que la implementación quede a cargo del framework.&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Ahora, nuestro Service cuenta con un DAO que tiene:&lt;br /&gt;
* Métodos definidos en él;&lt;br /&gt;
* Métodos provistos por PagingAndSortingRepository;&lt;br /&gt;
* Métodos provistos por CustomTareaDao. &lt;br /&gt;
&lt;br /&gt;
¿Y las implementaciones?&lt;br /&gt;
&lt;br /&gt;
Las implementaciones de los métodos definidos en TareaDao y los heredados de PagingAndSortingRepository, nos las va a proveer el framework. Y para la interfaz CustomTareaDao nosotros debemos definir nuestro DaoImpl común y corriente.&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
A la hora de testear, debemos tener un test (en nuestro caso es TareaDaoComponenteTest) que testee de la interfaz DAO que exponemos (es decír, TareaDao): &lt;br /&gt;
* Los métodos definidos manualmente en el DAO siguiendo la nomenclatura específica del framework. Ej: List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
* Los métodos definidos en la interfaz creada para los métodos específicos (CustomTareaDao). Ej: ScrollableResults buscarResumenHoras(FiltroResumenHorasDto filtro);&lt;br /&gt;
&lt;br /&gt;
===Test===&lt;br /&gt;
Como estamos delegando la responsabilidad de la implementación del DAO en un framework, y como ni siquiera sabemos como es la implementación dado que se produce en runtime, decidimos no testear aquellos métodos ya tenemos definidos al heredar de alguna de las interfaces que nos provee la herramienta.&lt;br /&gt;
Sin embargo, sí decidimos testear la capa del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA, además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
==Mas==&lt;br /&gt;
&lt;br /&gt;
===SELECT DISTINCT===&lt;br /&gt;
&lt;br /&gt;
====Situación a resolver====&lt;br /&gt;
Necesitamos recuperar todos los clientes, tal que alguno de los servicios de los clientes cumpla con una condición determinada.&lt;br /&gt;
&lt;br /&gt;
====Primera solución====&lt;br /&gt;
Creamos un método:&lt;br /&gt;
 List&amp;lt;Cliente&amp;gt; findByServiciosEstado(EstadosServicios estado);&lt;br /&gt;
&lt;br /&gt;
====Problema====&lt;br /&gt;
El método traía repetidos los clientes por cada uno de sus servicios que cumplían con la condición.&lt;br /&gt;
&lt;br /&gt;
=====Contexto=====&lt;br /&gt;
* Spring Data JPA, version 1.0.3.RELEASE.&lt;br /&gt;
&lt;br /&gt;
=====Solución=====&lt;br /&gt;
Al método le agregamos la keyword Distinct delante del By:&lt;br /&gt;
  List&amp;lt;Cliente&amp;gt; findDistinctByServiciosEstado(EstadosServicios estado);&lt;br /&gt;
&lt;br /&gt;
=====Comentario adicional=====&lt;br /&gt;
El problema de esto es que la keyword no está en la [http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/#repository-query-keywords| documentación oficial de Spring Data JPA].&lt;br /&gt;
Sin embargo, encontramos una [https://jira.springsource.org/browse/DATAJPA-174?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab| issue en el Jira de Spring Data JPA] sobre el tema.&lt;br /&gt;
&lt;br /&gt;
Por último, [http://static.springsource.org/spring-data/data-jpa/docs/1.0.0.RELEASE/changelog.txt| en el changelog de la versión] se indica que está soportado.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Proyecto de ejemplo===&lt;br /&gt;
Pueden descargarse un proyecto de ejemplo haciendo un checkout mediante un cliente de SVN de:&lt;br /&gt;
 http://dosideas-aplicaciones-modelo.googlecode.com/svn/trunk/spring-data/trunk&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6607</id>
		<title>Spring Data</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6607"/>
				<updated>2012-05-08T15:22:56Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introducción==&lt;br /&gt;
La herramienta que encontramos útil para dejar de hacer manualmente las implementaciones de los DAO que suelen ser siempre de la misma manera, fué a través de Spring Data JPA. [http://www.springsource.org/spring-data/jpa|http://www.springsource.org/spring-data/jpa]&lt;br /&gt;
&lt;br /&gt;
Este framework nos permite, siguiendo una serie de normas que nos establece, crear interfaces de DAOs definiendo métodos y NO realizar ninguna implementación. Es decir, dejamos la responsabilidad de la implementación al framework, el cuál hará la implementación en tiempo de corrida.&lt;br /&gt;
Para ello, el framework básicamente lo que hace es buscar, dado un paquete que le indicamos por configuración, todas las interfaces que hereden de org.springframework.data.repository.Repository&amp;lt;T, ID extends Serializable&amp;gt; ya sea directa o indirectamente.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Spring-Data-JPA-Herencia repository.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Configuración==&lt;br /&gt;
&lt;br /&gt;
===Dependencias (Utilizando Maven)===&lt;br /&gt;
Para trabajar con Spring Data JPA, solo debemos agregar la dependencia:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
      &amp;lt;groupId&amp;gt;org.springframework.data&amp;lt;/groupId&amp;gt;&lt;br /&gt;
      &amp;lt;artifactId&amp;gt;spring-data-jpa&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
      &amp;lt;version&amp;gt;1.0.3.RELEASE&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siempre y cuando contemos con una configuración de persistencia que utilice:&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.orm.jpa.JpaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;entityManagerFactory&amp;quot; ref=&amp;quot;entityManagerFactory&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaDialect&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaDialect&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/bean&amp;gt;&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;entityManagerFactory&amp;quot; class=&amp;quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;defaultDataSource&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;property name=&amp;quot;generateDdl&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
           &amp;lt;/bean&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configurando el paquete a escanear===&lt;br /&gt;
&lt;br /&gt;
En el applicationContext.xml:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:jpa=&amp;quot;http://www.springframework.org/schema/data/jpa&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;br /&gt;
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    &amp;lt;!-- Declara los repositorios de datos. Se implementarán automáticamente todas&lt;br /&gt;
         las interfaces que hereden de Repository (o CrudRepository).&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;jpa:repositories base-package=&amp;quot;com.th.ctc.dao&amp;quot; /&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
 &amp;lt;/beans&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementación==&lt;br /&gt;
===El ejemplo fácil===&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.CrudRepository;&lt;br /&gt;
 import com.th.ctc.domain.Cliente;&lt;br /&gt;
 /**&lt;br /&gt;
  * Interfaz del DAO para la entidad {@link Cliente}. Esta interfaz NO tiene una&lt;br /&gt;
  * implementacion concreta dado que al extender de Repository la implementacion&lt;br /&gt;
  * la hace en runtime Spring Data JPA.&lt;br /&gt;
  * &lt;br /&gt;
  * @author Alguien.&lt;br /&gt;
  */&lt;br /&gt;
 public interface ClienteDao extends CrudRepository&amp;lt;Cliente, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de clientes.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private ClienteDao clienteDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Cliente&amp;gt; buscarTodos() {&lt;br /&gt;
      return (List&amp;lt;Cliente&amp;gt;) clienteDao.findAll(); //El método findAll() proviene de CrudRepository&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===El ejemplo habitual===&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Usuario;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz del DAO para la entidad {@link Usuario}. Esta interfaz NO tiene una&lt;br /&gt;
 * implementacion concreta dado que al extender de Repository la implementación&lt;br /&gt;
 * la hace en runtime Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface UsuarioDao extends PagingAndSortingRepository&amp;lt;Usuario, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de usuarios.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private UsuarioDao usuarioDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Usuario&amp;gt; buscarTodos() {&lt;br /&gt;
      // El método findAll(Sort) proviene de PagingAndSortingRepository y con el String &amp;quot;apellido&amp;quot; (es el nombre del &lt;br /&gt;
      // atributo de clase de la entidad Usuario) estamos indicando que se ordenaran los resultados por ese campo&lt;br /&gt;
      return (List&amp;lt;Usuario&amp;gt;) usuarioDao.findAll(new Sort(&amp;quot;apellido&amp;quot;)); &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
===El ejemplo dificil===&lt;br /&gt;
Supongamos que ahora necesitamos 2 cosas:&lt;br /&gt;
Por un lado, recuperar todos los elementos de una entidad, recuperar uno solo en base al ID y etc., y por otro, generar un archivo Excel con información recuperada de una consulta a una base de datos muy específica.&lt;br /&gt;
Para lograr esto, aprovechando esta herramienta, necesitamos 2 interfaces del DAO. Una para definir estos métodos tan complejos que necesitamos, y otra para utilizar de la misma manera que en el ejemplo fácil.&lt;br /&gt;
&lt;br /&gt;
¿Pero entonces el Service tiene que utilizar 2 DAOs distintos sobre la misma entidad?&lt;br /&gt;
&lt;br /&gt;
No. Antes que nada, veamos un diagrama de clases para que veamos por qué este es el ejemplo dificil:&lt;br /&gt;
[[Media:Ejemplo complejo Spring Data JPA.PNG|Diagrama de clases]]&lt;br /&gt;
&lt;br /&gt;
Es decir, tenemos un Service (TareaServiceImpl) que utiliza un DAO (TareaDao). Nada nuevo hasta acá. Sin embargo, este TareaDao no solo hereda de Repository al heredar de org.springframework.data.repository.PagingAndSortingRepository, sino que también está heredando de una interfaz definida por nosotros (CustomTareaDao).&lt;br /&gt;
&lt;br /&gt;
¿Por qué necesitamos esto?&lt;br /&gt;
&lt;br /&gt;
Bueno, por que si bien podemos definir métodos en la interfaz que hereda de Repository, estos métodos tienen que seguir una nomenclatura específica para que el framework pueda hacer la implementación y, además, porque no podemos definir métodos que no queremos que los implemente Spring Data JPA para implementarlos nosotros.&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
&lt;br /&gt;
 import java.util.Date;&lt;br /&gt;
 import java.util.List;&lt;br /&gt;
 import org.springframework.data.domain.Sort;&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Tarea;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz el DAO de las {@link Tarea} implementado por Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface TareaDao extends PagingAndSortingRepository&amp;lt;Tarea, Long&amp;gt;, CustomTareaDao {&lt;br /&gt;
    /**&lt;br /&gt;
     * Recupera todas las tareas del usuario que le pasamos, para la fecha dada.&lt;br /&gt;
     * &lt;br /&gt;
     * @author Alguien.&lt;br /&gt;
     * @param idUsuario&lt;br /&gt;
     *            {@link Long} con el ID del usuario duenio de la tarea.&lt;br /&gt;
     * @param fechaDesde&lt;br /&gt;
     *            {@link Date} la fecha desde la cual se buscara.&lt;br /&gt;
     * @param fechaHasta&lt;br /&gt;
     *            {@link Date} la fecha hasta la cual se buscara.&lt;br /&gt;
     * @param sort&lt;br /&gt;
     *            {@link Sort} de Spring Data JPA utilizado para ordenar los&lt;br /&gt;
     *            resultados segun cierto criterio.&lt;br /&gt;
     * @return {@link List&amp;lt;Tarea&amp;gt;} Las tareas encontradas.&lt;br /&gt;
     */&lt;br /&gt;
    List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Como vemos, estamos definiendo un método '''findByUsuarioIdAndFechaBetween''' que sigue la nomenclatura del framework para recuperar un listado de tareas en base al Id del Usuario que le pasamos, entre un rango de fechas dado, y que al definir con esta nomenclatura hacemos que la implementación quede a cargo del framework.&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Ahora, nuestro Service cuenta con un DAO que tiene:&lt;br /&gt;
* Métodos definidos en él;&lt;br /&gt;
* Métodos provistos por PagingAndSortingRepository;&lt;br /&gt;
* Métodos provistos por CustomTareaDao. &lt;br /&gt;
&lt;br /&gt;
¿Y las implementaciones?&lt;br /&gt;
&lt;br /&gt;
Las implementaciones de los métodos definidos en TareaDao y los heredados de PagingAndSortingRepository, nos las va a proveer el framework. Y para la interfaz CustomTareaDao nosotros debemos definir nuestro DaoImpl común y corriente.&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
A la hora de testear, debemos tener un test (en nuestro caso es TareaDaoComponenteTest) que testee de la interfaz DAO que exponemos (es decír, TareaDao): &lt;br /&gt;
* Los métodos definidos manualmente en el DAO siguiendo la nomenclatura específica del framework. Ej: List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
* Los métodos definidos en la interfaz creada para los métodos específicos (CustomTareaDao). Ej: ScrollableResults buscarResumenHoras(FiltroResumenHorasDto filtro);&lt;br /&gt;
&lt;br /&gt;
===Test===&lt;br /&gt;
Como estamos delegando la responsabilidad de la implementación del DAO en un framework, y como ni siquiera sabemos como es la implementación dado que se produce en runtime, decidimos no testear aquellos métodos ya tenemos definidos al heredar de alguna de las interfaces que nos provee la herramienta.&lt;br /&gt;
Sin embargo, sí decidimos testear la capa del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA, además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
==Mas==&lt;br /&gt;
Pueden descargarse un proyecto de ejemplo haciendo un checkout mediante un cliente de SVN de:&lt;br /&gt;
 http://dosideas-aplicaciones-modelo.googlecode.com/svn/trunk/spring-data/trunk&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6606</id>
		<title>Spring Data</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6606"/>
				<updated>2012-05-08T15:16:40Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: /* El ejemplo dificil */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introducción==&lt;br /&gt;
La herramienta que encontramos útil para dejar de hacer manualmente las implementaciones de los DAO que suelen ser siempre de la misma manera, fué a través de Spring Data JPA. [http://www.springsource.org/spring-data/jpa|http://www.springsource.org/spring-data/jpa]&lt;br /&gt;
&lt;br /&gt;
Este framework nos permite, siguiendo una serie de normas que nos establece, crear interfaces de DAOs definiendo métodos y NO realizar ninguna implementación. Es decir, dejamos la responsabilidad de la implementación al framework, el cuál hará la implementación en tiempo de corrida.&lt;br /&gt;
Para ello, el framework básicamente lo que hace es buscar, dado un paquete que le indicamos por configuración, todas las interfaces que hereden de org.springframework.data.repository.Repository&amp;lt;T, ID extends Serializable&amp;gt; ya sea directa o indirectamente.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Spring-Data-JPA-Herencia repository.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Configuración==&lt;br /&gt;
&lt;br /&gt;
===Dependencias (Utilizando Maven)===&lt;br /&gt;
Para trabajar con Spring Data JPA, solo debemos agregar la dependencia:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
      &amp;lt;groupId&amp;gt;org.springframework.data&amp;lt;/groupId&amp;gt;&lt;br /&gt;
      &amp;lt;artifactId&amp;gt;spring-data-jpa&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
      &amp;lt;version&amp;gt;1.0.3.RELEASE&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siempre y cuando contemos con una configuración de persistencia que utilice:&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.orm.jpa.JpaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;entityManagerFactory&amp;quot; ref=&amp;quot;entityManagerFactory&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaDialect&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaDialect&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/bean&amp;gt;&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;entityManagerFactory&amp;quot; class=&amp;quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;defaultDataSource&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;property name=&amp;quot;generateDdl&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
           &amp;lt;/bean&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configurando el paquete a escanear===&lt;br /&gt;
&lt;br /&gt;
En el applicationContext.xml:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:jpa=&amp;quot;http://www.springframework.org/schema/data/jpa&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;br /&gt;
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    &amp;lt;!-- Declara los repositorios de datos. Se implementarán automáticamente todas&lt;br /&gt;
         las interfaces que hereden de Repository (o CrudRepository).&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;jpa:repositories base-package=&amp;quot;com.th.ctc.dao&amp;quot; /&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
 &amp;lt;/beans&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementación==&lt;br /&gt;
===El ejemplo fácil===&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.CrudRepository;&lt;br /&gt;
 import com.th.ctc.domain.Cliente;&lt;br /&gt;
 /**&lt;br /&gt;
  * Interfaz del DAO para la entidad {@link Cliente}. Esta interfaz NO tiene una&lt;br /&gt;
  * implementacion concreta dado que al extender de Repository la implementacion&lt;br /&gt;
  * la hace en runtime Spring Data JPA.&lt;br /&gt;
  * &lt;br /&gt;
  * @author Alguien.&lt;br /&gt;
  */&lt;br /&gt;
 public interface ClienteDao extends CrudRepository&amp;lt;Cliente, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de clientes.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private ClienteDao clienteDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Cliente&amp;gt; buscarTodos() {&lt;br /&gt;
      return (List&amp;lt;Cliente&amp;gt;) clienteDao.findAll(); //El método findAll() proviene de CrudRepository&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===El ejemplo habitual===&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Usuario;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz del DAO para la entidad {@link Usuario}. Esta interfaz NO tiene una&lt;br /&gt;
 * implementacion concreta dado que al extender de Repository la implementación&lt;br /&gt;
 * la hace en runtime Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface UsuarioDao extends PagingAndSortingRepository&amp;lt;Usuario, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de usuarios.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private UsuarioDao usuarioDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Usuario&amp;gt; buscarTodos() {&lt;br /&gt;
      // El método findAll(Sort) proviene de PagingAndSortingRepository y con el String &amp;quot;apellido&amp;quot; (es el nombre del &lt;br /&gt;
      // atributo de clase de la entidad Usuario) estamos indicando que se ordenaran los resultados por ese campo&lt;br /&gt;
      return (List&amp;lt;Usuario&amp;gt;) usuarioDao.findAll(new Sort(&amp;quot;apellido&amp;quot;)); &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
===El ejemplo dificil===&lt;br /&gt;
Supongamos que ahora necesitamos 2 cosas:&lt;br /&gt;
Por un lado, recuperar todos los elementos de una entidad, recuperar uno solo en base al ID y etc., y por otro, generar un archivo Excel con información recuperada de una consulta a una base de datos muy específica.&lt;br /&gt;
Para lograr esto, aprovechando esta herramienta, necesitamos 2 interfaces del DAO. Una para definir estos métodos tan complejos que necesitamos, y otra para utilizar de la misma manera que en el ejemplo fácil.&lt;br /&gt;
&lt;br /&gt;
¿Pero entonces el Service tiene que utilizar 2 DAOs distintos sobre la misma entidad?&lt;br /&gt;
&lt;br /&gt;
No. Antes que nada, veamos un diagrama de clases para que veamos por qué este es el ejemplo dificil:&lt;br /&gt;
[[Media:Ejemplo complejo Spring Data JPA.PNG|Diagrama de clases]]&lt;br /&gt;
&lt;br /&gt;
Es decir, tenemos un Service (TareaServiceImpl) que utiliza un DAO (TareaDao). Nada nuevo hasta acá. Sin embargo, este TareaDao no solo hereda de Repository al heredar de org.springframework.data.repository.PagingAndSortingRepository, sino que también está heredando de una interfaz definida por nosotros (CustomTareaDao).&lt;br /&gt;
&lt;br /&gt;
¿Por qué necesitamos esto?&lt;br /&gt;
&lt;br /&gt;
Bueno, por que si bien podemos definir métodos en la interfaz que hereda de Repository, estos métodos tienen que seguir una nomenclatura específica para que el framework pueda hacer la implementación y, además, porque no podemos definir métodos que no queremos que los implemente Spring Data JPA para implementarlos nosotros.&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
&lt;br /&gt;
 import java.util.Date;&lt;br /&gt;
 import java.util.List;&lt;br /&gt;
 import org.springframework.data.domain.Sort;&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Tarea;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz el DAO de las {@link Tarea} implementado por Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface TareaDao extends PagingAndSortingRepository&amp;lt;Tarea, Long&amp;gt;, CustomTareaDao {&lt;br /&gt;
    /**&lt;br /&gt;
     * Recupera todas las tareas del usuario que le pasamos, para la fecha dada.&lt;br /&gt;
     * &lt;br /&gt;
     * @author Alguien.&lt;br /&gt;
     * @param idUsuario&lt;br /&gt;
     *            {@link Long} con el ID del usuario duenio de la tarea.&lt;br /&gt;
     * @param fechaDesde&lt;br /&gt;
     *            {@link Date} la fecha desde la cual se buscara.&lt;br /&gt;
     * @param fechaHasta&lt;br /&gt;
     *            {@link Date} la fecha hasta la cual se buscara.&lt;br /&gt;
     * @param sort&lt;br /&gt;
     *            {@link Sort} de Spring Data JPA utilizado para ordenar los&lt;br /&gt;
     *            resultados segun cierto criterio.&lt;br /&gt;
     * @return {@link List&amp;lt;Tarea&amp;gt;} Las tareas encontradas.&lt;br /&gt;
     */&lt;br /&gt;
    List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Como vemos, estamos definiendo un método '''findByUsuarioIdAndFechaBetween''' que sigue la nomenclatura del framework para recuperar un listado de tareas en base al Id del Usuario que le pasamos, entre un rango de fechas dado, y que al definir con esta nomenclatura hacemos que la implementación quede a cargo del framework.&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Ahora, nuestro Service cuenta con un DAO que tiene:&lt;br /&gt;
* Métodos definidos en él;&lt;br /&gt;
* Métodos provistos por PagingAndSortingRepository;&lt;br /&gt;
* Métodos provistos por CustomTareaDao. &lt;br /&gt;
&lt;br /&gt;
¿Y las implementaciones?&lt;br /&gt;
&lt;br /&gt;
Las implementaciones de los métodos definidos en TareaDao y los heredados de PagingAndSortingRepository, nos las va a proveer el framework. Y para la interfaz CustomTareaDao nosotros debemos definir nuestro DaoImpl común y corriente.&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
A la hora de testear, debemos tener un test (en nuestro caso es TareaDaoComponenteTest) que testee de la interfaz DAO que exponemos (es decír, TareaDao): &lt;br /&gt;
* Los métodos definidos manualmente en el DAO siguiendo la nomenclatura específica del framework. Ej: List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
* Los métodos definidos en la interfaz creada para los métodos específicos (CustomTareaDao). Ej: ScrollableResults buscarResumenHoras(FiltroResumenHorasDto filtro);&lt;br /&gt;
&lt;br /&gt;
===Test===&lt;br /&gt;
Como estamos delegando la responsabilidad de la implementación del DAO en un framework, y como ni siquiera sabemos como es la implementación dado que se produce en runtime, decidimos no testear aquellos métodos ya tenemos definidos al heredar de alguna de las interfaces que nos provee la herramienta.&lt;br /&gt;
Sin embargo, sí decidimos testear la capa del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA, además claro de la lógica propia del Service.&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6605</id>
		<title>Spring Data</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6605"/>
				<updated>2012-05-08T15:10:40Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: /* El ejemplo dificil */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introducción==&lt;br /&gt;
La herramienta que encontramos útil para dejar de hacer manualmente las implementaciones de los DAO que suelen ser siempre de la misma manera, fué a través de Spring Data JPA. [http://www.springsource.org/spring-data/jpa|http://www.springsource.org/spring-data/jpa]&lt;br /&gt;
&lt;br /&gt;
Este framework nos permite, siguiendo una serie de normas que nos establece, crear interfaces de DAOs definiendo métodos y NO realizar ninguna implementación. Es decir, dejamos la responsabilidad de la implementación al framework, el cuál hará la implementación en tiempo de corrida.&lt;br /&gt;
Para ello, el framework básicamente lo que hace es buscar, dado un paquete que le indicamos por configuración, todas las interfaces que hereden de org.springframework.data.repository.Repository&amp;lt;T, ID extends Serializable&amp;gt; ya sea directa o indirectamente.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Spring-Data-JPA-Herencia repository.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Configuración==&lt;br /&gt;
&lt;br /&gt;
===Dependencias (Utilizando Maven)===&lt;br /&gt;
Para trabajar con Spring Data JPA, solo debemos agregar la dependencia:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
      &amp;lt;groupId&amp;gt;org.springframework.data&amp;lt;/groupId&amp;gt;&lt;br /&gt;
      &amp;lt;artifactId&amp;gt;spring-data-jpa&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
      &amp;lt;version&amp;gt;1.0.3.RELEASE&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siempre y cuando contemos con una configuración de persistencia que utilice:&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.orm.jpa.JpaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;entityManagerFactory&amp;quot; ref=&amp;quot;entityManagerFactory&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaDialect&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaDialect&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/bean&amp;gt;&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;entityManagerFactory&amp;quot; class=&amp;quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;defaultDataSource&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;property name=&amp;quot;generateDdl&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
           &amp;lt;/bean&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configurando el paquete a escanear===&lt;br /&gt;
&lt;br /&gt;
En el applicationContext.xml:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:jpa=&amp;quot;http://www.springframework.org/schema/data/jpa&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;br /&gt;
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    &amp;lt;!-- Declara los repositorios de datos. Se implementarán automáticamente todas&lt;br /&gt;
         las interfaces que hereden de Repository (o CrudRepository).&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;jpa:repositories base-package=&amp;quot;com.th.ctc.dao&amp;quot; /&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
 &amp;lt;/beans&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementación==&lt;br /&gt;
===El ejemplo fácil===&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.CrudRepository;&lt;br /&gt;
 import com.th.ctc.domain.Cliente;&lt;br /&gt;
 /**&lt;br /&gt;
  * Interfaz del DAO para la entidad {@link Cliente}. Esta interfaz NO tiene una&lt;br /&gt;
  * implementacion concreta dado que al extender de Repository la implementacion&lt;br /&gt;
  * la hace en runtime Spring Data JPA.&lt;br /&gt;
  * &lt;br /&gt;
  * @author Alguien.&lt;br /&gt;
  */&lt;br /&gt;
 public interface ClienteDao extends CrudRepository&amp;lt;Cliente, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de clientes.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private ClienteDao clienteDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Cliente&amp;gt; buscarTodos() {&lt;br /&gt;
      return (List&amp;lt;Cliente&amp;gt;) clienteDao.findAll(); //El método findAll() proviene de CrudRepository&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===El ejemplo habitual===&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Usuario;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz del DAO para la entidad {@link Usuario}. Esta interfaz NO tiene una&lt;br /&gt;
 * implementacion concreta dado que al extender de Repository la implementación&lt;br /&gt;
 * la hace en runtime Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface UsuarioDao extends PagingAndSortingRepository&amp;lt;Usuario, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de usuarios.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private UsuarioDao usuarioDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Usuario&amp;gt; buscarTodos() {&lt;br /&gt;
      // El método findAll(Sort) proviene de PagingAndSortingRepository y con el String &amp;quot;apellido&amp;quot; (es el nombre del &lt;br /&gt;
      // atributo de clase de la entidad Usuario) estamos indicando que se ordenaran los resultados por ese campo&lt;br /&gt;
      return (List&amp;lt;Usuario&amp;gt;) usuarioDao.findAll(new Sort(&amp;quot;apellido&amp;quot;)); &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
===El ejemplo dificil===&lt;br /&gt;
Supongamos que ahora necesitamos 2 cosas:&lt;br /&gt;
Por un lado, recuperar todos los elementos de una entidad, recuperar uno solo en base al ID y etc., y por otro, generar un archivo Excel con información recuperada de una consulta a una base de datos muy específica.&lt;br /&gt;
Para lograr esto, aprovechando esta herramienta, necesitamos 2 interfaces del DAO. Una para definir estos métodos tan complejos que necesitamos, y otra para utilizar de la misma manera que en el ejemplo fácil.&lt;br /&gt;
&lt;br /&gt;
¿Pero entonces el Service tiene que utilizar 2 DAOs distintos sobre la misma entidad?&lt;br /&gt;
&lt;br /&gt;
No. Antes que nada, veamos un diagrama de clases para que veamos por qué este es el ejemplo dificil:&lt;br /&gt;
[[Archivo:Ejemplo complejo Spring Data JPA.PNG|thumb|left|hola]]&lt;br /&gt;
&lt;br /&gt;
Es decir, tenemos un Service (TareaServiceImpl) que utiliza un DAO (TareaDao). Nada nuevo hasta acá. Sin embargo, este TareaDao no solo hereda de Repository al heredar de org.springframework.data.repository.PagingAndSortingRepository, sino que también está heredando de una interfaz definida por nosotros (CustomTareaDao).&lt;br /&gt;
&lt;br /&gt;
¿Por qué necesitamos esto?&lt;br /&gt;
&lt;br /&gt;
Bueno, por que si bien podemos definir métodos en la interfaz que hereda de Repository, estos métodos tienen que seguir una nomenclatura específica para que el framework pueda hacer la implementación y, además, porque no podemos definir métodos que no queremos que los implemente Spring Data JPA para implementarlos nosotros.&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
&lt;br /&gt;
 import java.util.Date;&lt;br /&gt;
 import java.util.List;&lt;br /&gt;
 import org.springframework.data.domain.Sort;&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Tarea;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz el DAO de las {@link Tarea} implementado por Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface TareaDao extends PagingAndSortingRepository&amp;lt;Tarea, Long&amp;gt;, CustomTareaDao {&lt;br /&gt;
    /**&lt;br /&gt;
     * Recupera todas las tareas del usuario que le pasamos, para la fecha dada.&lt;br /&gt;
     * &lt;br /&gt;
     * @author Alguien.&lt;br /&gt;
     * @param idUsuario&lt;br /&gt;
     *            {@link Long} con el ID del usuario duenio de la tarea.&lt;br /&gt;
     * @param fechaDesde&lt;br /&gt;
     *            {@link Date} la fecha desde la cual se buscara.&lt;br /&gt;
     * @param fechaHasta&lt;br /&gt;
     *            {@link Date} la fecha hasta la cual se buscara.&lt;br /&gt;
     * @param sort&lt;br /&gt;
     *            {@link Sort} de Spring Data JPA utilizado para ordenar los&lt;br /&gt;
     *            resultados segun cierto criterio.&lt;br /&gt;
     * @return {@link List&amp;lt;Tarea&amp;gt;} Las tareas encontradas.&lt;br /&gt;
     */&lt;br /&gt;
    List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Como vemos, estamos definiendo un método '''findByUsuarioIdAndFechaBetween''' que sigue la nomenclatura del framework para recuperar un listado de tareas en base al Id del Usuario que le pasamos, entre un rango de fechas dado, y que al definir con esta nomenclatura hacemos que la implementación quede a cargo del framework.&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Ahora, nuestro Service cuenta con un DAO que tiene:&lt;br /&gt;
* Métodos definidos en él;&lt;br /&gt;
* Métodos provistos por PagingAndSortingRepository;&lt;br /&gt;
* Métodos provistos por CustomTareaDao. &lt;br /&gt;
&lt;br /&gt;
¿Y las implementaciones?&lt;br /&gt;
&lt;br /&gt;
Las implementaciones de los métodos definidos en TareaDao y los heredados de PagingAndSortingRepository, nos las va a proveer el framework. Y para la interfaz CustomTareaDao nosotros debemos definir nuestro DaoImpl común y corriente.&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
A la hora de testear, debemos tener un test (en nuestro caso es TareaDaoComponenteTest) que testee de la interfaz DAO que exponemos (es decír, TareaDao): &lt;br /&gt;
* Los métodos definidos manualmente en el DAO siguiendo la nomenclatura específica del framework. Ej: List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
* Los métodos definidos en la interfaz creada para los métodos específicos (CustomTareaDao). Ej: ScrollableResults buscarResumenHoras(FiltroResumenHorasDto filtro);&lt;br /&gt;
&lt;br /&gt;
===Test===&lt;br /&gt;
Como estamos delegando la responsabilidad de la implementación del DAO en un framework, y como ni siquiera sabemos como es la implementación dado que se produce en runtime, decidimos no testear aquellos métodos ya tenemos definidos al heredar de alguna de las interfaces que nos provee la herramienta.&lt;br /&gt;
Sin embargo, sí decidimos testear la capa del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA, además claro de la lógica propia del Service.&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6604</id>
		<title>Spring Data</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6604"/>
				<updated>2012-05-08T15:07:24Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: /* El ejemplo dificil */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introducción==&lt;br /&gt;
La herramienta que encontramos útil para dejar de hacer manualmente las implementaciones de los DAO que suelen ser siempre de la misma manera, fué a través de Spring Data JPA. [http://www.springsource.org/spring-data/jpa|http://www.springsource.org/spring-data/jpa]&lt;br /&gt;
&lt;br /&gt;
Este framework nos permite, siguiendo una serie de normas que nos establece, crear interfaces de DAOs definiendo métodos y NO realizar ninguna implementación. Es decir, dejamos la responsabilidad de la implementación al framework, el cuál hará la implementación en tiempo de corrida.&lt;br /&gt;
Para ello, el framework básicamente lo que hace es buscar, dado un paquete que le indicamos por configuración, todas las interfaces que hereden de org.springframework.data.repository.Repository&amp;lt;T, ID extends Serializable&amp;gt; ya sea directa o indirectamente.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Spring-Data-JPA-Herencia repository.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Configuración==&lt;br /&gt;
&lt;br /&gt;
===Dependencias (Utilizando Maven)===&lt;br /&gt;
Para trabajar con Spring Data JPA, solo debemos agregar la dependencia:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
      &amp;lt;groupId&amp;gt;org.springframework.data&amp;lt;/groupId&amp;gt;&lt;br /&gt;
      &amp;lt;artifactId&amp;gt;spring-data-jpa&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
      &amp;lt;version&amp;gt;1.0.3.RELEASE&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siempre y cuando contemos con una configuración de persistencia que utilice:&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.orm.jpa.JpaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;entityManagerFactory&amp;quot; ref=&amp;quot;entityManagerFactory&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaDialect&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaDialect&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/bean&amp;gt;&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;entityManagerFactory&amp;quot; class=&amp;quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;defaultDataSource&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;property name=&amp;quot;generateDdl&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
           &amp;lt;/bean&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configurando el paquete a escanear===&lt;br /&gt;
&lt;br /&gt;
En el applicationContext.xml:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:jpa=&amp;quot;http://www.springframework.org/schema/data/jpa&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;br /&gt;
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    &amp;lt;!-- Declara los repositorios de datos. Se implementarán automáticamente todas&lt;br /&gt;
         las interfaces que hereden de Repository (o CrudRepository).&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;jpa:repositories base-package=&amp;quot;com.th.ctc.dao&amp;quot; /&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
 &amp;lt;/beans&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementación==&lt;br /&gt;
===El ejemplo fácil===&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.CrudRepository;&lt;br /&gt;
 import com.th.ctc.domain.Cliente;&lt;br /&gt;
 /**&lt;br /&gt;
  * Interfaz del DAO para la entidad {@link Cliente}. Esta interfaz NO tiene una&lt;br /&gt;
  * implementacion concreta dado que al extender de Repository la implementacion&lt;br /&gt;
  * la hace en runtime Spring Data JPA.&lt;br /&gt;
  * &lt;br /&gt;
  * @author Alguien.&lt;br /&gt;
  */&lt;br /&gt;
 public interface ClienteDao extends CrudRepository&amp;lt;Cliente, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de clientes.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private ClienteDao clienteDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Cliente&amp;gt; buscarTodos() {&lt;br /&gt;
      return (List&amp;lt;Cliente&amp;gt;) clienteDao.findAll(); //El método findAll() proviene de CrudRepository&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===El ejemplo habitual===&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Usuario;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz del DAO para la entidad {@link Usuario}. Esta interfaz NO tiene una&lt;br /&gt;
 * implementacion concreta dado que al extender de Repository la implementación&lt;br /&gt;
 * la hace en runtime Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface UsuarioDao extends PagingAndSortingRepository&amp;lt;Usuario, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de usuarios.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private UsuarioDao usuarioDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Usuario&amp;gt; buscarTodos() {&lt;br /&gt;
      // El método findAll(Sort) proviene de PagingAndSortingRepository y con el String &amp;quot;apellido&amp;quot; (es el nombre del &lt;br /&gt;
      // atributo de clase de la entidad Usuario) estamos indicando que se ordenaran los resultados por ese campo&lt;br /&gt;
      return (List&amp;lt;Usuario&amp;gt;) usuarioDao.findAll(new Sort(&amp;quot;apellido&amp;quot;)); &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
===El ejemplo dificil===&lt;br /&gt;
Supongamos que ahora necesitamos 2 cosas:&lt;br /&gt;
Por un lado, recuperar todos los elementos de una entidad, recuperar uno solo en base al ID y etc., y por otro, generar un archivo Excel con información recuperada de una consulta a una base de datos muy específica.&lt;br /&gt;
Para lograr esto, aprovechando esta herramienta, necesitamos 2 interfaces del DAO. Una para definir estos métodos tan complejos que necesitamos, y otra para utilizar de la misma manera que en el ejemplo fácil.&lt;br /&gt;
&lt;br /&gt;
¿Pero entonces el Service tiene que utilizar 2 DAOs distintos sobre la misma entidad?&lt;br /&gt;
&lt;br /&gt;
No. Antes que nada, veamos un diagrama de clases para que veamos por qué este es el ejemplo dificil:&lt;br /&gt;
[[Archivo:Ejemplo complejo Spring Data JPA.PNG|601px]]&lt;br /&gt;
&lt;br /&gt;
Es decir, tenemos un Service (TareaServiceImpl) que utiliza un DAO (TareaDao). Nada nuevo hasta acá. Sin embargo, este TareaDao no solo hereda de Repository al heredar de org.springframework.data.repository.PagingAndSortingRepository, sino que también está heredando de una interfaz definida por nosotros (CustomTareaDao).&lt;br /&gt;
&lt;br /&gt;
¿Por qué necesitamos esto?&lt;br /&gt;
&lt;br /&gt;
Bueno, por que si bien podemos definir métodos en la interfaz que hereda de Repository, estos métodos tienen que seguir una nomenclatura específica para que el framework pueda hacer la implementación y, además, porque no podemos definir métodos que no queremos que los implemente Spring Data JPA para implementarlos nosotros.&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
&lt;br /&gt;
 import java.util.Date;&lt;br /&gt;
 import java.util.List;&lt;br /&gt;
 import org.springframework.data.domain.Sort;&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Tarea;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz el DAO de las {@link Tarea} implementado por Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface TareaDao extends PagingAndSortingRepository&amp;lt;Tarea, Long&amp;gt;, CustomTareaDao {&lt;br /&gt;
    /**&lt;br /&gt;
     * Recupera todas las tareas del usuario que le pasamos, para la fecha dada.&lt;br /&gt;
     * &lt;br /&gt;
     * @author Alguien.&lt;br /&gt;
     * @param idUsuario&lt;br /&gt;
     *            {@link Long} con el ID del usuario duenio de la tarea.&lt;br /&gt;
     * @param fechaDesde&lt;br /&gt;
     *            {@link Date} la fecha desde la cual se buscara.&lt;br /&gt;
     * @param fechaHasta&lt;br /&gt;
     *            {@link Date} la fecha hasta la cual se buscara.&lt;br /&gt;
     * @param sort&lt;br /&gt;
     *            {@link Sort} de Spring Data JPA utilizado para ordenar los&lt;br /&gt;
     *            resultados segun cierto criterio.&lt;br /&gt;
     * @return {@link List&amp;lt;Tarea&amp;gt;} Las tareas encontradas.&lt;br /&gt;
     */&lt;br /&gt;
    List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Como vemos, estamos definiendo un método '''findByUsuarioIdAndFechaBetween''' que sigue la nomenclatura del framework para recuperar un listado de tareas en base al Id del Usuario que le pasamos, entre un rango de fechas dado, y que al definir con esta nomenclatura hacemos que la implementación quede a cargo del framework.&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Ahora, nuestro Service cuenta con un DAO que tiene:&lt;br /&gt;
* Métodos definidos en él;&lt;br /&gt;
* Métodos provistos por PagingAndSortingRepository;&lt;br /&gt;
* Métodos provistos por CustomTareaDao. &lt;br /&gt;
&lt;br /&gt;
¿Y las implementaciones?&lt;br /&gt;
&lt;br /&gt;
Las implementaciones de los métodos definidos en TareaDao y los heredados de PagingAndSortingRepository, nos las va a proveer el framework. Y para la interfaz CustomTareaDao nosotros debemos definir nuestro DaoImpl común y corriente.&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
A la hora de testear, debemos tener un test (en nuestro caso es TareaDaoComponenteTest) que testee de la interfaz DAO que exponemos (es decír, TareaDao): &lt;br /&gt;
* Los métodos definidos manualmente en el DAO siguiendo la nomenclatura específica del framework. Ej: List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
* Los métodos definidos en la interfaz creada para los métodos específicos (CustomTareaDao). Ej: ScrollableResults buscarResumenHoras(FiltroResumenHorasDto filtro);&lt;br /&gt;
&lt;br /&gt;
===Test===&lt;br /&gt;
Como estamos delegando la responsabilidad de la implementación del DAO en un framework, y como ni siquiera sabemos como es la implementación dado que se produce en runtime, decidimos no testear aquellos métodos ya tenemos definidos al heredar de alguna de las interfaces que nos provee la herramienta.&lt;br /&gt;
Sin embargo, sí decidimos testear la capa del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA, además claro de la lógica propia del Service.&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Archivo:Ejemplo_complejo_Spring_Data_JPA.PNG&amp;diff=6603</id>
		<title>Archivo:Ejemplo complejo Spring Data JPA.PNG</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Archivo:Ejemplo_complejo_Spring_Data_JPA.PNG&amp;diff=6603"/>
				<updated>2012-05-08T15:03:03Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: Ejemplo de interfaz DAO utilizando Spring Data JPA y extendiendo además de una interfaz propia.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ejemplo de interfaz DAO utilizando Spring Data JPA y extendiendo además de una interfaz propia.&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6602</id>
		<title>Spring Data</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6602"/>
				<updated>2012-05-08T15:01:28Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: Creo la página con ejemplos de Spring Data JPA&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introducción==&lt;br /&gt;
La herramienta que encontramos útil para dejar de hacer manualmente las implementaciones de los DAO que suelen ser siempre de la misma manera, fué a través de Spring Data JPA. [http://www.springsource.org/spring-data/jpa|http://www.springsource.org/spring-data/jpa]&lt;br /&gt;
&lt;br /&gt;
Este framework nos permite, siguiendo una serie de normas que nos establece, crear interfaces de DAOs definiendo métodos y NO realizar ninguna implementación. Es decir, dejamos la responsabilidad de la implementación al framework, el cuál hará la implementación en tiempo de corrida.&lt;br /&gt;
Para ello, el framework básicamente lo que hace es buscar, dado un paquete que le indicamos por configuración, todas las interfaces que hereden de org.springframework.data.repository.Repository&amp;lt;T, ID extends Serializable&amp;gt; ya sea directa o indirectamente.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Spring-Data-JPA-Herencia repository.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Configuración==&lt;br /&gt;
&lt;br /&gt;
===Dependencias (Utilizando Maven)===&lt;br /&gt;
Para trabajar con Spring Data JPA, solo debemos agregar la dependencia:&lt;br /&gt;
 &amp;lt;dependency&amp;gt;&lt;br /&gt;
      &amp;lt;groupId&amp;gt;org.springframework.data&amp;lt;/groupId&amp;gt;&lt;br /&gt;
      &amp;lt;artifactId&amp;gt;spring-data-jpa&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
      &amp;lt;version&amp;gt;1.0.3.RELEASE&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;/dependency&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siempre y cuando contemos con una configuración de persistencia que utilice:&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.orm.jpa.JpaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;entityManagerFactory&amp;quot; ref=&amp;quot;entityManagerFactory&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaDialect&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaDialect&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
 &amp;lt;/bean&amp;gt;&lt;br /&gt;
 &amp;lt;bean id=&amp;quot;entityManagerFactory&amp;quot; class=&amp;quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;defaultDataSource&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;jpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;property name=&amp;quot;generateDdl&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
           &amp;lt;/bean&amp;gt;&lt;br /&gt;
      &amp;lt;/property&amp;gt;&lt;br /&gt;
  &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configurando el paquete a escanear===&lt;br /&gt;
&lt;br /&gt;
En el applicationContext.xml:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:jpa=&amp;quot;http://www.springframework.org/schema/data/jpa&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;br /&gt;
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    &amp;lt;!-- Declara los repositorios de datos. Se implementarán automáticamente todas&lt;br /&gt;
         las interfaces que hereden de Repository (o CrudRepository).&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;jpa:repositories base-package=&amp;quot;com.th.ctc.dao&amp;quot; /&amp;gt;&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
 &amp;lt;/beans&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementación==&lt;br /&gt;
===El ejemplo fácil===&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.CrudRepository;&lt;br /&gt;
 import com.th.ctc.domain.Cliente;&lt;br /&gt;
 /**&lt;br /&gt;
  * Interfaz del DAO para la entidad {@link Cliente}. Esta interfaz NO tiene una&lt;br /&gt;
  * implementacion concreta dado que al extender de Repository la implementacion&lt;br /&gt;
  * la hace en runtime Spring Data JPA.&lt;br /&gt;
  * &lt;br /&gt;
  * @author Alguien.&lt;br /&gt;
  */&lt;br /&gt;
 public interface ClienteDao extends CrudRepository&amp;lt;Cliente, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de clientes.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private ClienteDao clienteDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Cliente&amp;gt; buscarTodos() {&lt;br /&gt;
      return (List&amp;lt;Cliente&amp;gt;) clienteDao.findAll(); //El método findAll() proviene de CrudRepository&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===El ejemplo habitual===&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
Para este ejemplo sencillo, la interfaz del DAO va a quedar sin métodos definidos explicitamente, pero con todos aquellos que estamos heredando.&lt;br /&gt;
&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Usuario;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz del DAO para la entidad {@link Usuario}. Esta interfaz NO tiene una&lt;br /&gt;
 * implementacion concreta dado que al extender de Repository la implementación&lt;br /&gt;
 * la hace en runtime Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface UsuarioDao extends PagingAndSortingRepository&amp;lt;Usuario, Long&amp;gt; {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Hasta acá llegamos. A partir de ahora no hay mas código vinculado con el DAO más que el uso de los métodos que estamos exponiendo en la interfaz que nosotros mismos creamos. Por lo tanto nuestro Service sería algo como:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * DAO de usuarios.&lt;br /&gt;
  */&lt;br /&gt;
 @Autowired&lt;br /&gt;
 private UsuarioDao usuarioDao;&lt;br /&gt;
 @Override&lt;br /&gt;
 public List&amp;lt;Usuario&amp;gt; buscarTodos() {&lt;br /&gt;
      // El método findAll(Sort) proviene de PagingAndSortingRepository y con el String &amp;quot;apellido&amp;quot; (es el nombre del &lt;br /&gt;
      // atributo de clase de la entidad Usuario) estamos indicando que se ordenaran los resultados por ese campo&lt;br /&gt;
      return (List&amp;lt;Usuario&amp;gt;) usuarioDao.findAll(new Sort(&amp;quot;apellido&amp;quot;)); &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
Como no hay una implementación concreta, y de haber, no la hacemos nosotros sino que estamos delegando la responsabilidad al framework, no hacemos tests de la capa DAO, pero si del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA además claro de la lógica propia del Service.&lt;br /&gt;
&lt;br /&gt;
===El ejemplo dificil===&lt;br /&gt;
Supongamos que ahora necesitamos 2 cosas:&lt;br /&gt;
Por un lado, recuperar todos los elementos de una entidad, recuperar uno solo en base al ID y etc., y por otro, generar un archivo Excel con información recuperada de una consulta a una base de datos muy específica.&lt;br /&gt;
Para lograr esto, aprovechando esta herramienta, necesitamos 2 interfaces del DAO. Una para definir estos métodos tan complejos que necesitamos, y otra para utilizar de la misma manera que en el ejemplo fácil.&lt;br /&gt;
&lt;br /&gt;
¿Pero entonces el Service tiene que utilizar 2 DAOs distintos sobre la misma entidad?&lt;br /&gt;
&lt;br /&gt;
No. Antes que nada, veamos un diagrama de clases para que veamos por qué este es el ejemplo dificil:&lt;br /&gt;
[[Archivo:Ejemplo complejo Spring Data JPA.PNG]]&lt;br /&gt;
&lt;br /&gt;
Es decir, tenemos un Service (TareaServiceImpl) que utiliza un DAO (TareaDao). Nada nuevo hasta acá. Sin embargo, este TareaDao no solo hereda de Repository al heredar de org.springframework.data.repository.PagingAndSortingRepository, sino que también está heredando de una interfaz definida por nosotros (CustomTareaDao).&lt;br /&gt;
&lt;br /&gt;
¿Por qué necesitamos esto?&lt;br /&gt;
&lt;br /&gt;
Bueno, por que si bien podemos definir métodos en la interfaz que hereda de Repository, estos métodos tienen que seguir una nomenclatura específica para que el framework pueda hacer la implementación y, además, porque no podemos definir métodos que no queremos que los implemente Spring Data JPA para implementarlos nosotros.&lt;br /&gt;
&lt;br /&gt;
====Definiendo la interfaz del DAO====&lt;br /&gt;
&lt;br /&gt;
 import java.util.Date;&lt;br /&gt;
 import java.util.List;&lt;br /&gt;
 import org.springframework.data.domain.Sort;&lt;br /&gt;
 import org.springframework.data.repository.PagingAndSortingRepository;&lt;br /&gt;
 import com.th.ctc.domain.Tarea;&lt;br /&gt;
 /**&lt;br /&gt;
 * Interfaz el DAO de las {@link Tarea} implementado por Spring Data JPA.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Alguien.&lt;br /&gt;
 */&lt;br /&gt;
 public interface TareaDao extends PagingAndSortingRepository&amp;lt;Tarea, Long&amp;gt;, CustomTareaDao {&lt;br /&gt;
    /**&lt;br /&gt;
     * Recupera todas las tareas del usuario que le pasamos, para la fecha dada.&lt;br /&gt;
     * &lt;br /&gt;
     * @author Alguien.&lt;br /&gt;
     * @param idUsuario&lt;br /&gt;
     *            {@link Long} con el ID del usuario duenio de la tarea.&lt;br /&gt;
     * @param fechaDesde&lt;br /&gt;
     *            {@link Date} la fecha desde la cual se buscara.&lt;br /&gt;
     * @param fechaHasta&lt;br /&gt;
     *            {@link Date} la fecha hasta la cual se buscara.&lt;br /&gt;
     * @param sort&lt;br /&gt;
     *            {@link Sort} de Spring Data JPA utilizado para ordenar los&lt;br /&gt;
     *            resultados segun cierto criterio.&lt;br /&gt;
     * @return {@link List&amp;lt;Tarea&amp;gt;} Las tareas encontradas.&lt;br /&gt;
     */&lt;br /&gt;
    List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Como vemos, estamos definiendo un método '''findByUsuarioIdAndFechaBetween''' que sigue la nomenclatura del framework para recuperar un listado de tareas en base al Id del Usuario que le pasamos, entre un rango de fechas dado, y que al definir con esta nomenclatura hacemos que la implementación quede a cargo del framework.&lt;br /&gt;
&lt;br /&gt;
====Usando el DAO desde el Service====&lt;br /&gt;
Ahora, nuestro Service cuenta con un DAO que tiene:&lt;br /&gt;
* Métodos definidos en él;&lt;br /&gt;
* Métodos provistos por PagingAndSortingRepository;&lt;br /&gt;
* Métodos provistos por CustomTareaDao. &lt;br /&gt;
&lt;br /&gt;
¿Y las implementaciones?&lt;br /&gt;
&lt;br /&gt;
Las implementaciones de los métodos definidos en TareaDao y los heredados de PagingAndSortingRepository, nos las va a proveer el framework. Y para la interfaz CustomTareaDao nosotros debemos definir nuestro DaoImpl común y corriente.&lt;br /&gt;
&lt;br /&gt;
====Test====&lt;br /&gt;
A la hora de testear, debemos tener un test (en nuestro caso es TareaDaoComponenteTest) que testee de la interfaz DAO que exponemos (es decír, TareaDao): &lt;br /&gt;
* Los métodos definidos manualmente en el DAO siguiendo la nomenclatura específica del framework. Ej: List&amp;lt;Tarea&amp;gt; findByUsuarioIdAndFechaBetween(Long idUsuario, Date fechaDesde, Date fechaHasta, Sort sort);&lt;br /&gt;
* Los métodos definidos en la interfaz creada para los métodos específicos (CustomTareaDao). Ej: ScrollableResults buscarResumenHoras(FiltroResumenHorasDto filtro);&lt;br /&gt;
&lt;br /&gt;
===Test===&lt;br /&gt;
Como estamos delegando la responsabilidad de la implementación del DAO en un framework, y como ni siquiera sabemos como es la implementación dado que se produce en runtime, decidimos no testear aquellos métodos ya tenemos definidos al heredar de alguna de las interfaces que nos provee la herramienta.&lt;br /&gt;
Sin embargo, sí decidimos testear la capa del Service donde probamos que estamos utilizando correctamente lo que nos provee Spring DATA JPA, además claro de la lógica propia del Service.&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Archivo:Spring-Data-JPA-Herencia_repository.PNG&amp;diff=6601</id>
		<title>Archivo:Spring-Data-JPA-Herencia repository.PNG</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Archivo:Spring-Data-JPA-Herencia_repository.PNG&amp;diff=6601"/>
				<updated>2012-05-08T15:00:28Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: Muestro la herencia de las interfaces de Spring Data JPA:
Repository; CrudRepository; PagingAndSortingRepository.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Muestro la herencia de las interfaces de Spring Data JPA:&lt;br /&gt;
Repository; CrudRepository; PagingAndSortingRepository.&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6600</id>
		<title>Spring Data</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Data&amp;diff=6600"/>
				<updated>2012-05-08T14:52:38Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: Página creada con 'asdasdasdasd'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;asdasdasdasd&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Desarrollo_De_Software&amp;diff=6599</id>
		<title>Desarrollo De Software</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Desarrollo_De_Software&amp;diff=6599"/>
				<updated>2012-05-08T14:52:05Z</updated>
		
		<summary type="html">&lt;p&gt;Barrios.nahuel: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;El desarrollo de software involucra no sólo el uso de [[Metodologias De Desarrollo]], sino la aplicación de tecnologías de desarrollo y testing para asegurar la calidad del producto.&lt;br /&gt;
&lt;br /&gt;
== Libros ==&lt;br /&gt;
* [[Libros]]&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [[HTML]]&lt;br /&gt;
* [[Javascript]]&lt;br /&gt;
* [[Java]]&lt;br /&gt;
* [[Diseño De Software]]&lt;br /&gt;
* [[Patrones]]&lt;br /&gt;
* [[Testing De Aplicaciones]]&lt;br /&gt;
* [[Base De Datos]]&lt;br /&gt;
* [[Herramientas Para Gestion De Calidad]]&lt;br /&gt;
* [[Performance De Aplicaciones]]&lt;br /&gt;
* [[Spring Data]]&lt;/div&gt;</summary>
		<author><name>Barrios.nahuel</name></author>	</entry>

	</feed>