Diferencia entre revisiones de «Hibernate Annotations con Spring»
(Página creada con 'Category:Hibernate Para utilizar las anotaciones de Hibernate junto con Spring tenemos que reemplazar en el archivo application-hibernate.xml la clase org.springfram…') |
(→Anotando Colecciones) |
||
(No se muestran 13 ediciones intermedias de 3 usuarios) | |||
Línea 1: | Línea 1: | ||
[[Category:Hibernate]] | [[Category:Hibernate]] | ||
− | Para utilizar las anotaciones de [[Hibernate]] junto con [[Spring]] tenemos que reemplazar en el archivo application-hibernate.xml la clase org.springframework.orm.hibernate3.LocalSessionFactoryBean por org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean: | + | |
+ | 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 == | == Ejemplo de uso == | ||
− | <code | + | <code xml> |
<bean id="sessionFactory" | <bean id="sessionFactory" | ||
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> | class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> | ||
Línea 11: | Línea 27: | ||
<property name="annotatedClasses"> | <property name="annotatedClasses"> | ||
<list> | <list> | ||
− | |||
<value>com.app.domain.Cliente</value> | <value>com.app.domain.Cliente</value> | ||
</list> | </list> | ||
Línea 24: | Línea 39: | ||
</code> | </code> | ||
− | == Querys con Spring == | + | == Querys con Spring y Mapeos== |
− | <code | + | <code java5> |
@Entity | @Entity | ||
@Table (name="cliente") | @Table (name="cliente") | ||
Línea 48: | Línea 63: | ||
} | } | ||
</code> | </code> | ||
− | + | ||
== DAO == | == DAO == | ||
− | <code | + | <code java5> |
public class ClienteDaoImpl extends HibernateDaoSupport implements ClienteDao { | public class ClienteDaoImpl extends HibernateDaoSupport implements ClienteDao { | ||
Línea 70: | 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'''. |
− | |||
− | <code | + | <code xml> |
<bean id="sessionFactory" | <bean id="sessionFactory" | ||
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> | class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> | ||
Línea 99: | 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 == | ||
+ | |||
+ | <code java5> | ||
+ | @Column(name = "FEC_ALTA") | ||
+ | @Temporal(TemporalType.TIMESTAMP) | ||
+ | @org.hibernate.annotations.Generated(org.hibernate.annotations.GenerationTime.INSERT) | ||
+ | private Date fechaAlta; | ||
+ | </code> | ||
+ | |||
+ | 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. |
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:
Contenido
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.