Friday, July 29, 2011

Creando la Base de Datos




Para hacer a nuestra aplicación persistente, necesitamos usar algún tipo de almacenamiento, en este tutorial emplearemos un servidor de bases de datos relacionales, para ser más específicos usaremos MySQL 5.

La aplicación es bastante simple, por lo que emplearemos únicamente una tabla para almacenar nuestros datos. La tabla la creamos con el siguiente script SQL:

CREATE SCHEMA IF NOT EXISTS `springtutorial` DEFAULT CHARACTER SET utf8 ;
USE `springtutorial` ;

CREATE  TABLE `springtutorial`.`movies` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`title` VARCHAR(45) NULL DEFAULT NULL ,
`director` VARCHAR(45) NULL DEFAULT NULL ,
`actors` VARCHAR(100) NULL DEFAULT NULL ,
`duration` INT(11) NULL DEFAULT NULL ,
PRIMARY KEY (`id`) )
AUTO_INCREMENT = 3;

Una vez creada nuestra base de datos vamos a empezar a realizar nuestras entidades. Las entidades son clases que representan a una tabla en una base de datos, éstas son especificadas por el estandar JPA (Java Persistence API) a través de implementaciones como Hibernate o TopLink.

Para tener  soporte de Hibernate en nuestro proyecto tenemos que editar el pom.xml y agregar las siguientes dependencias:
<dependency>
   <groupid>org.hibernate</groupid>
   <artifactid>hibernate-core</artifactid>
   <version>3.6.2.Final</version>
</dependency>
<dependency>
   <groupid>javassist</groupid>
   <artifactid>javassist</artifactid>
   <version>3.10.0.GA</version>
</dependency>

<dependency>
   <groupid>org.springframework</groupid>
   <artifactid>spring-orm</artifactid>
   <version>${org.springframework-version}</version>
</dependency>


Ahora empezaremos a mapear nuestra tabla para poder manejar libremente instancias de esa clase que representarán a un registro en la base de datos.

//Imports omitidos

@Entity
@Table(name="movies")
public class Movie {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String title;
private String director;
private String actors;
private Integer duration; 
//Getters y Setters
}
Una vez escrito el código presionamos: Ctrl + Shit + O para agregar automáticamente los imports necesarios. El anterior es un mapeo muy básico de los datos, a continuación detallo lo que hace cada anotación:
  • @Entity : Indica que ésta clase está mapeando hacia una tabla en una base de datos, aunque todavía no sabemos hacía que tabla lo hace.
  • @Table : Ya que sabemos que ésta clase es una entidad, indicamos hacía que tabla lo hace.
  • @Id : Pasando a las anotaciones que tienen efecto sobre los campos (columnas en la BD), tenemos esta anotación. Cada entidad debe de tener una "identificación" que regularmente es la llave primaria en la tabla, aunque puede ser también una llave compuesta por dos o más columnas de la tabla.
  • @GeneratedValue : Ahora que ya conocemos el campo que distingue a un registro de otro, debemos indicar cómo se obtiene este valor. Previamente en nuestra tabla definimos que el campo "id" sería autoincrementado; por lo anterior la técnica que usaremos es "Automática".
  • Nota: Los nombres de los campos deben coincidir con los nombres de las columnas en la tabla, sin embargo para mejor lectura del código y ayudar a la comprensión podemos hacer uso de la anotación @Column mediante la cual podemos indicar el nombre de la columna a la cual mapea.
Cabe mencionar que dentro de Eclipse (y STS) se tiene la opción de crear un proyecto de JPA, mediante el cuál se puede hacer un proceso de "ingeniería inversa" y generar las entidades directamente de la base de datos. Personalmente no recomiendo este método ya que, si bien funciona en mapeos básicos, al momento de tener relaciones entre tablas empieza a tener errores en los mapeos.
Ahora que ya tenemos la capa que mapea empezaremos a construir la siguiente capa, llamada "DAO", que tiene como propósito simplificar las operaciones de creación, lectura, actualización y borrado de registros.

Monday, July 25, 2011

Device not Managed

Continuing with my experience installing Debian Squeeze, I found with another trouble: I couldn't connect trough my WiFi card, and all the information I was given was: "Device not managed".

I did know that it wasn't due of a misconfigured driver, because during the installation Debian downloaded some packages and updates using this interface. So I started to dig in the Debian (and Network Manager) documentation. I found two causes for this message:

  1. The file /etc/network/interfaces has a reference to the interface that we're trying to use
  2. The configuration file for NetworkManager(/etc/NetworkManager/NetworkManager.conf)
    defines the property:
    [ifupdown]
    managed=false


This is due to the default configuration in Debian Squeeze, this means that any interface defined in /etc/network/interfaces is not managed, the thing is, if you connected to internet during the installation (packages and/or updates) the interface you used automatically was added to that file.

The solution to this is to modify the configuration:
tepeyolotl@satellite: /$ sudo gedit /etc/NetworkManager/NetworkManager

In this file we rewrite the configuration for the desired interface:
[ifupdown]
managed=true

Now, we must restart the service in order to the changes take place:
tepeyolotl@satellite: /$ sudo service network-manager restart
[sudo] password for tepeyolotl:
Stopping network connection manager: NetworkManager.
Starting network connection manager: NetworkManager.

And now we have connection trough our "unmanaged" interface.

Wednesday, July 20, 2011

Creando proyecto en STS

Agregando Tomcat a STS

SpringSource Tool Suite incluye un servidor de aplicaciones (tcServer), sin embargo, como hemos dicho, usaremos Tomcat Server 6 como servidor de  aplicaciones. Para poder hacer despliegues directamente en el servidor, además de permitir el control del servidor desde el mismo IDE, debemos agregarlo a la lista de servidores; para hacerlo damos click derecho en la ventana de "Servers" y seleccionamos New->Server (igualmente esta disponible en File->New->Other) y seleccionamos las siguientes opciones:

En la última opción(Server Runtime environment) damos click en Add e introducimos los datos que nos piden (nombre y ubicación de la instalación)

Y al terminar el asistente tendremos el servidor en la ventana de Servers.

Creando el proyecto


Teniendo instalado el ambiente de desarrollo iniciaremos SpringSource Tool Suite, y a continuación seleccionaremos File->New->Spring Template Project.
En esta ventana seleccionaremos la opción Spring MVC Project, esto creará un proyecto con configuraciones de Spring a partir del cual construiremos nuestro proyecto. A continuación especificaremos el nombre del proyecto y el package que estaremos manejando.
Una vez finalizado el asistente veremos que el proyecto que recientemente creamos tiene la estructura:


Monday, July 18, 2011

Tutorial de Spring 3

Cuando empecé a desarrollar aplicaciones con Spring me di cuenta de que había relativamente pocos tutoriales, y menos aún los que detallaban el porqué de las cosas en el código que se posteaba; así pues me dispuse a hacer este tutorial de una aplicación web de manera que muestre ventajas de desarrollar con Spring.

Introducción

El proyecto Spring es uno de los frameworks más populares para el lenguaje Java. Está enfocado (pero no limitado) al desarrollo de aplicaciones web, y que, uno de sus conceptos fundamentales es la Inyección de dependencias que es realizada por un contenedor. Gracias a ésta "inyección" es posible optimizar la aplicación, ya que permite el reuso de componentes básicos, tales como conexiones a base de datos u objetos que no son específicos al usuario.

El modelo MVC

Uno de los modelos más difundidos para el desarrollo de aplicaciones web es el llamado MVC (Model View Controller), que quiere decir "Modelo Vista Controlador". Pero, ¿qué es cada cosa?, pues bien se puede definir de la siguiente manera:
  • Modelo: Es el conjunto de objetos que son necesarios para interactuar con la página web, por ejemplo: un objeto con nombre de usuario, una lista de comentarios, un carrito de compras etc.
  • Vista: Es la representación gráfica del modelo, e incluye toda la página donde se "rendereó" el modelo. Por ejemplo: una tabla con datos, un formulario etc.
  • Controlador: Es el encargado de manejar las peticiones HTTP y ejecutar los métodos adecuados para generar el modelo y posteriormente retornar la vista al usuario que la solicitó

A lo largo de este tutorial veremos cómo se vinculan estos conceptos.


La aplicación

El objetivo del tutorial es desarrollar una aplicación básica que maneje una base de datos de películas, para lograr esto emplearemos otros frameworks, para así tener una aplicación más robusta y por lo tanto más próxima a un escenario real. Las herramientas a utilizar serán:
  • SpringSource Tool Suite 2.6: El IDE basado en Eclipse de los mismos desarrolladores del framework, aunque también se puede usar Eclipse for Java EE
  • Hibernate 3.6.2: Para manejar la base de datos de manera más simple y segura a través de éste framework de persistencia
  • Maven 2: Simplifica las tareas de compilar el proyecto y mantener una lista de dependencias del mismo.
  • Apache Tomcat 6: Utilizaremos el popular servidor para desplegar nuestra aplicación
Sin más aquí iré actualizando  el indice:
  1. Configurando STS y creando el proyecto. 
  2. Creando la base de Datos y Persistencia

    Wednesday, July 6, 2011

    "Dispositivo no manejado" en tarjeta de red inalámbrica

    Continuando con mi experiencia instalando Debian Squeeze me encontré con el problema de que Debian no levantaba la interfaz correspondiente a la tarjeta de red inalámbrica. El mensaje que mostraba el "Network Manager" era "Dispositivo no manejado".
    Se podía descartar el driver de la tarjeta, ya que al momento de instalar el SO
    con soporte de red, ésta detecto y se conectó por esta interfaz sin problema
    alguno. Así que empecé a buscar en la documentación del Network Manager,
    específicamente sobre el mensaje mostrado, por lo cual encontré que hay dos
    causas para este mensaje:
    1. El archivo /etc/network/interfaces contiene alguna referencia para el
      dispositivo que estamos tratando de usar
    2. El archivo de configuración del Network Manager (/etc/NetworkManager/NetworkManager.conf)
      define la propiedad:
      [ifupdown]
      managed=false
    Esto debido a que desde Debian Squeeze está desactivado por default el manejar cualquier interfaz definida en /etc/network/interfaces, y es lógico que no levantara la interfaz ya que al momento de instalar el sistema y dar los datos de conexión, se agregó la interfaz usada al archivo /etc/network/interfaces.

    Para solucionar este inconveniente simplemente tenemos que modificar la configuración con
    tepeyolotl@satellite: /$ sudo gedit /etc/NetworkManager/NetworkManager


    Y dentro de este archivo la propiedad anteriormente mencionada queda de la siguiente forma:
    [ifupdown]
    managed=true
    


    Para que el Network Manager tome los cambios realizados ejecutamos:
    tepeyolotl@satellite: /$ sudo service network-manager restart
    [sudo] password for tepeyolotl: 
    Stopping network connection manager: NetworkManager.
    Starting network connection manager: NetworkManager.
    


    Y con eso ya se puede conectar a través de la interfaz deseada.

    Wednesday, June 22, 2011

    Adding Windows to GRUB in Debian Squeeze

    Recently I installed Debian 6 Squeeze on my notebook, where I already have an installation of Windows 7 Professional. For work reasons I couldn't delete this installation, so I installed Debian on a logical partition. During the installation everything went good, even at the moment of the GRUB configuration (GRUB detected the Windows Loader), but when I booted for the first time there wasn't an option to boot Windows. So this is the steps I made to add the menu entry.

    The first step is to check the names of the partitions:

    tepeyolotl@satellite:/$ sudo fdisk -l|grep NTFS
    [sudo] password for tepeyolotl: 
    /dev/sda1   *           1          13      102400    7  HPFS/NTFS
    /dev/sda2              13       16908   135705600    7  HPFS/NTFS
    tepeyolotl@satellite:/$ 
    

    The fdisk command is only available to the superuser (you can also execute all of this commands from a root terminal), th -l option lists the devices and the outputis piped to the grep to be filtered. We note that the partition we search for is listed in "/dev/sda2".

    The next step is create a script to indicate this info to the GRUB.

    tepeyolotl@satellite:/$ sudo gedit /etc/grub.d/11_windows
    

    This command opens the file (if it doesn't exists, it will be created), due to the directory in which we're working we need to execute this command as superuser. In the file we should type this:

    #!/bin/bash
    cat<<EOF
    menuentry "Windows 7 Professional"{
    set root(hd0,2)
    chainloader (hd0,2)+1
    }
    EOF
    

    The important thing here is the fragment "(hd0,2)" which indicates the partition with the OS that we are adding to the menu. Save the file, and give the file permissions as executable, after that, the only thing to do is update the grub.

    tepeyolotl@satellite:/$ sudo chmod +x /etc/grub.d/11_windows
    tepeyolotl@satellite:/$ sudo update-grub
    Generating grub.cfg ...
    Found background image: /usr/share/images/desktop-base/desktop-grub.png
    Found linux image: /boot/vmlinuz-2.6.32-5-686
    Found initrd image: /boot/initrd.img-2.6.32-5-686
    Found Windows 7 (loader) on /dev/sda1
    done
    tepeyolotl@satellite:/$
    

    And that's all, the menu entry is now ready to start Windows 7.

    Agregar Windows al GRUB desde Debian 6 Squeeze

    Recientemente instalé Debian 6 Squeeze en mi computadora, que previamente tenía instalado Windows 7 Professional. Como no quería deshacerme de Windows por motivos de trabajo, instalé Debian en una partición lógica.

    Durante la instalación todo iba bien, incluso al generar el menú de arranque del GRUB detectó correctamente el arranque previo de Windows 7 en la otra partición, así que me despreocupé. Grande fue mi sorpresa al ver que una vez finalizado todo el proceso de instalación, la entrada que debiera arrancar Windows 7 no estaba en el menú de GRUB.

    Leyendo en los release notes de GRUB 2 (que es el que maneja Debian Squeeze), descubrí que no había error, ya que GRUB2 detectó la partición pero jamás la agregó. Así pues me di a la tarea de ver como se resolvería esto.

    Lo primero era ver que nombre tenían las particiones:

    tepeyolotl@satellite:/$ sudo fdisk -l|grep NTFS
    [sudo] password for tepeyolotl:
    /dev/sda1 * 1 13 102400 7 HPFS/NTFS
    /dev/sda2 13 16908 135705600 7 HPFS/NTFS
    tepeyolotl@satellite:/$

    El comando fdisk solo se encuentra disponible a través de root, y con el modificador -l listamos las particiones detectadas, para ser filtradas por el tipo NTFS (esa es la función del grep). Como ya conocemos el numero de partición que contiene el arranque de Windows 7 (/dev/sda2), procedemos a agregar un archivo para que la configuraciñon del grub lo lea:

    tepeyolotl@satellite:/$ sudo gedit /etc/grub.d/11_windows

    Con ese comando lo que hacemos es abrir el archivo mencionado con gedit y permisos de supersusuario (necesarios para trabajar en ese directorio). Una vez abierto el archivo se ingresa lo siguiente:

    #!/bin/bash
    cat<<EOF
    menuentry "Windows 7 Professional"{
    set root(hd0,2)
    chainloader (hd0,2)+1
    }
    EOF

    Lo importante aquí son los parametros que se le dan a "root", es decir la partición en donde está nuestro Windows. Guardamos el archivo, y de vuelta en consola le damos los permisos necesarios, y actualizamos el grub.

    tepeyolotl@satellite:/$ sudo chmod +x /etc/grub.d/11_windows
    tepeyolotl@satellite:/$ sudo update-grub
    Generating grub.cfg ...
    Found background image: /usr/share/images/desktop-base/desktop-grub.png
    Found linux image: /boot/vmlinuz-2.6.32-5-686
    Found initrd image: /boot/initrd.img-2.6.32-5-686
    Found Windows 7 (loader) on /dev/sda1
    done
    tepeyolotl@satellite:/$

    Y bueno eso es todo y ya se puede ver la entrada para arrancar Windows 7 en el menú de GRUB.