Diferencia entre revisiones de «Hibernate Annotations con Spring»

De Dos Ideas.
Saltar a: navegación, buscar
(Anotando Colecciones)
 
(No se muestran 8 ediciones intermedias de 3 usuarios)
Línea 20: Línea 20:
 
== Ejemplo de uso ==
 
== Ejemplo de uso ==
  
<code html4strict>
+
<code xml>
 
  <bean id="sessionFactory"  
 
  <bean id="sessionFactory"  
 
   class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 
   class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
Línea 41: Línea 41:
 
== Querys con Spring y Mapeos==
 
== Querys con Spring y Mapeos==
  
<code html4strict>
+
<code java5>
 
  @Entity  
 
  @Entity  
 
  @Table (name="cliente")  
 
  @Table (name="cliente")  
Línea 63: Línea 63:
 
  }
 
  }
 
</code>
 
</code>
 
+
 
 
== DAO ==
 
== DAO ==
  
<code html4strict>
+
<code java5>
 
  public class ClienteDaoImpl extends  HibernateDaoSupport implements ClienteDao {
 
  public class ClienteDaoImpl extends  HibernateDaoSupport implements ClienteDao {
 
   
 
   
Línea 85: Línea 85:
 
En el archivo de configuración application-hibernate.xml se puede mezclar el mapeo a archivos xml y a clases anotadas sin problemas. Esto nos será muy útil al momento de "migrar" una aplicación de mapeo en archivos xml a clases anotadas, pudiendo hacer la migración en forma progresiva.
 
En el archivo de configuración application-hibernate.xml se puede mezclar el mapeo a archivos xml y a clases anotadas sin problemas. Esto nos será muy útil al momento de "migrar" una aplicación de mapeo en archivos xml a clases anotadas, pudiendo hacer la migración en forma progresiva.
  
La clase del SessionFactory que se debe utilizar en estos casos tambien es:
+
La clase del SessionFactory que se debe utilizar en estos casos tambien es '''org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean'''.
org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
 
  
<code html4strict>
+
<code xml>
 
  <bean id="sessionFactory"  
 
  <bean id="sessionFactory"  
 
   class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 
   class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
Línea 114: Línea 113:
  
 
Noten que mientras los mapeos por archivos XML DEBEN nombrarse con / (barra) entre los directorios, las clases anotadas DEBEN nombrarse con . (punto).
 
Noten que mientras los mapeos por archivos XML DEBEN nombrarse con / (barra) entre los directorios, las clases anotadas DEBEN nombrarse con . (punto).
 +
 +
== Anotando Colecciones ==
 +
La forma de anotar una relación "uno a muchos" es la siguiente:
 +
<code java5>
 +
@Entity
 +
@Table(name = "CLASE_PADRE")
 +
public class ClasePadre {
 +
   
 +
    @OneToMany(fetch = FetchType.EAGER)
 +
    @JoinColumn(name = "ID_CLASE_PADRE")
 +
    @Fetch(FetchMode.SELECT)
 +
    private Collection<ClaseHija> hijas;
 +
...
 +
 +
@Entity
 +
@Table(name = "CLASE_HIJA")
 +
public class ClaseHija {
 +
 +
    @ManyToOne(fetch = FetchType.EAGER)
 +
    @JoinColumn(name = "ID_CLASE_PADRE")
 +
    private ClasePadre padre;
 +
</code>
 +
 +
El fetch type puede ser Lazy o Eager. Cuándo se setea en Eager, existe la posibilidad de que se obtengan los registros duplicados. Para evitar este comportamiento, existe el FetchMode.SELECT.
  
 
== Anotaciones de fechas ==
 
== Anotaciones de fechas ==
  
<code html4strict>
+
<code java5>
 
@Column(name = "FEC_ALTA")
 
@Column(name = "FEC_ALTA")
 
@Temporal(TemporalType.TIMESTAMP)
 
@Temporal(TemporalType.TIMESTAMP)

Revisión actual del 14:25 17 nov 2010


Para poder usar Annotations con Hibernate hay que incluir las siguientes librerías en el proyecto:

  • hibernate-commons-annotations.jar
  • hibernate-annotations.jar
  • ejb3-persistence.jar

Estas librerías se encuentran en la distribucion hibernate-annotations-3.3.1.GA.zip que es la versión compatible para la actual version de Hibernate Core que estamos usando (3.2.6).

Utilizando annotations evitamos tener un archivo XML aparte por cada mapeo de objeto-tablas.

Las annotations se utilizan en los POJO's y pueden ubicarse en los miembros de la clase o en los getters de cada miembro.

Con Annotations no solo tenemos la ventaja de tener el mapeo cercano al codigo evitando problemas de sincronizacion entre el codigo y los archivos XML, sino que tambien nos evita escritura ya que cada propiedad (miembro) es considerada por default como persistente, por lo tanto si en la base de datos se llama igual que en la clase, no hay necesidad de explicitarlo.

Para utilizar las anotaciones de Hibernate junto con Spring Framework tenemos que reemplazar en el archivo application-hibernate.xml la clase org.springframework.orm.hibernate3.LocalSessionFactoryBean por org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean:

Ejemplo de uso

<bean id="sessionFactory" 
 class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />   
 <property name="annotatedClasses">
    <list>
      <value>com.app.domain.Cliente</value>              
    </list>
  </property>
<property name="hibernateProperties">
 <props>      
    <prop key="hibernate.show_sql">true</prop>     
 </props>
</property>      
</bean> 

Querys con Spring y Mapeos

@Entity 
@Table (name="cliente") 

//DECLARO LOS QUERIES 
@NamedQueries(
 {@NamedQuery(name="buscarPorIdCliente",
    query="select a from Cliente a where a.idCliente= ?"),

 @NamedQuery(name="buscarPorIdSucursal", 
  query="select a from miTabla a where a.idSucursal= ?")})
public class Cliente{  
   @Id 
   @Column (name="COD_CLIENTE")
   private Long id;

   @Column (name="COD_SUCURSAL")    
   private String idSucursal;

   .................
}

DAO

public class ClienteDaoImpl extends  HibernateDaoSupport implements ClienteDao {

   public Collection buscarPorIdCliente(String idCliente) {
      return  getHibernateTemplate().
      findByNamedQuery("buscarPorIdCliente", idCliente);
   }

   public Collection buscarPorIdSucursal(String idSucursal) {
          return  getHibernateTemplate().
                   findByNamedQuery("buscarPorIdSucursal", idSucursal);     
   }
} 

Mapeo de Recursos y Mapeo de Clases Anotadas

En el archivo de configuración application-hibernate.xml se puede mezclar el mapeo a archivos xml y a clases anotadas sin problemas. Esto nos será muy útil al momento de "migrar" una aplicación de mapeo en archivos xml a clases anotadas, pudiendo hacer la migración en forma progresiva.

La clase del SessionFactory que se debe utilizar en estos casos tambien es org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean.

<bean id="sessionFactory" 
 class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />   
 <property name="annotatedClasses">
    <list>
      <value>com.app.domain.Cliente</value>              
    </list>
  </property>
 <property name="mappingResources">
    <list>
      <value>com/app/domain/Cliente</value>              
    </list>
  </property>
<property name="hibernateProperties">
 <props>      
    <prop key="hibernate.show_sql">true</prop>     
 </props>
</property>      
</bean> 

Noten que mientras los mapeos por archivos XML DEBEN nombrarse con / (barra) entre los directorios, las clases anotadas DEBEN nombrarse con . (punto).

Anotando Colecciones

La forma de anotar una relación "uno a muchos" es la siguiente: @Entity @Table(name = "CLASE_PADRE") public class ClasePadre {

   @OneToMany(fetch = FetchType.EAGER)
   @JoinColumn(name = "ID_CLASE_PADRE")
   @Fetch(FetchMode.SELECT)
   private Collection<ClaseHija> hijas;

...

@Entity @Table(name = "CLASE_HIJA") public class ClaseHija {

   @ManyToOne(fetch = FetchType.EAGER)
   @JoinColumn(name = "ID_CLASE_PADRE")
   private ClasePadre padre;

El fetch type puede ser Lazy o Eager. Cuándo se setea en Eager, existe la posibilidad de que se obtengan los registros duplicados. Para evitar este comportamiento, existe el FetchMode.SELECT.

Anotaciones de fechas

@Column(name = "FEC_ALTA") @Temporal(TemporalType.TIMESTAMP) @org.hibernate.annotations.Generated(org.hibernate.annotations.GenerationTime.INSERT) private Date fechaAlta;

Con la clase Generated se estará asignando la fecha default. En este caso, el default del campo es sysdate. Entonces, el campo FEC_ALTA quedará actualizado con el default del campo en la base de datos. Si la entidad se hubiere seteado con new Date, esa asignación no se tendría en cuenta y la fecha de la base de datos es la que si se tendría en cuenta.