Para utilizar gmail como servidor de correo con la seguridad activada he tenido que configurar el archivo php.ini descomentando la siguiente linea:
;extension=php_openssl.dll --> extension=php_openssl.dll
Despues, al reiniciar el apache me daba un error al cargar la libreria dinamica y para solucionarlo he tenido que copiar los archivos "libeay32.dll" y "ssleay32.dll" de la carpeta php a "c:/windows/system32".
Como ejemplo os pongo el siguiente código para que hagais la prueba. Hace falta la librería de phpmailer que yo la obtenido del siguiente enlace:
http://sourceforge.net/projects/phpmailer/files/phpmailer%20for%20php5_6/PHPMailer%20v5.1/PHPMailer_v5.1.zip/download
require_once('../classes/phpmailer.class.php');
//include("class.smtp.php"); // optional, gets called from within class.phpmailer.php if not already loaded
$mail = new PHPMailer();
$body = 'holaaaa';//file_get_contents('contents.html');
$body = eregi_replace("[\]",'',$body);
$mail->IsSMTP(); // telling the class to use SMTP
$mail->SMTPDebug = 1; // enables SMTP debug information (for testing)
// 1 = errors and messages
// 2 = messages only
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->SMTPSecure = "ssl"; // sets the prefix to the servier
$mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->Username = "nombre.cuenta.gmail"; // GMAIL username
$mail->Password = "password"; // GMAIL password
$mail->SetFrom('name@yourdomain.com', 'Yo mismo');
$mail->AddReplyTo("ggb191983@gmail.com","First Last");
$mail->Subject = "PHPMailer Test Subject via smtp (Gmail), basic";
$mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
$mail->MsgHTML($body);
$address = "destinatario@dominio.com";
$mail->AddAddress($address, "John Doe");
$mail->AddAttachment("images/phpmailer.gif"); // attachment
$mail->AddAttachment("images/phpmailer_mini.gif"); // attachment
$mail->isHTML(true);
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
martes, 24 de enero de 2012
miércoles, 11 de enero de 2012
Crear tipo enumerado para hibernate
Para crear el tipo enumerado en primer lugar he necesitado la clase que viene públicada en el enlace http://appfuse.org/display/APF/Java+5+Enums+Persistence+with+Hibernate y que añado a continuación.
package com.manager.types;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.type.NullableType;
import org.hibernate.type.TypeFactory;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
import org.jboss.logging.Logger;
public class GenericEnumUserType implements UserType, ParameterizedType {
private static final Logger log = Logger.getLogger(GenericEnumUserType.class);
private static final String DEFAULT_IDENTIFIER_METHOD_NAME = "name";
private static final String DEFAULT_VALUE_OF_METHOD_NAME = "valueOf";
private Class<? extends Enum> enumClass;
private Class<?> identifierType;
private Method identifierMethod;
private Method valueOfMethod;
private NullableType type;
private int[] sqlTypes;
public void setParameterValues(Properties parameters) {
String enumClassName = parameters.getProperty("enumClass");
try {
enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
} catch (ClassNotFoundException cfne) {
throw new HibernateException("Enum class not found", cfne);
}
String identifierMethodName = parameters.getProperty("identifierMethod", DEFAULT_IDENTIFIER_METHOD_NAME);
try {
identifierMethod = enumClass.getMethod(identifierMethodName, new Class[0]);
identifierType = identifierMethod.getReturnType();
} catch (Exception e) {
throw new HibernateException("Failed to obtain identifier method", e);
}
type = (NullableType) TypeFactory.basic(identifierType.getName());
if (type == null)
throw new HibernateException("Unsupported identifier type " + identifierType.getName());
sqlTypes = new int[] { type.sqlType() };
String valueOfMethodName = parameters.getProperty("valueOfMethod", DEFAULT_VALUE_OF_METHOD_NAME);
try {
valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[] { identifierType });
} catch (Exception e) {
throw new HibernateException("Failed to obtain valueOf method", e);
}
}
public Class returnedClass() {
return enumClass;
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
Object identifier = type.get(rs, names[0]);
if (rs.wasNull()) {
return null;
}
try {
return valueOfMethod.invoke(enumClass, new Object[] { identifier });
} catch (Exception e) {
throw new HibernateException("Exception while invoking valueOf method '" + valueOfMethod.getName() + "' of " +
"enumeration class '" + enumClass + "'", e);
}
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
try {
if (value == null) {
st.setNull(index, type.sqlType());
} else {
Object identifier = identifierMethod.invoke(value, new Object[0]);
type.set(st, identifier, index);
}
} catch (Exception e) {
throw new HibernateException("Exception while invoking identifierMethod '" + identifierMethod.getName() + "' of " +
"enumeration class '" + enumClass + "'", e);
}
}
public int[] sqlTypes() {
return sqlTypes;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public boolean equals(Object x, Object y) throws HibernateException {
return x == y;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public boolean isMutable() {
return false;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
Después he creado la clase enumerada "NewsState" que quería que se mapeara con su correspondiente tipo en la base de datos. Esta clase la he tenido que crear en su propio fichero .java sino no me funcionaba.
package com.manager.types;
public enum NewsState {
RELEASED,
NO_RELEASED,
DELETE
}
Una vez creado los tipos, he utilizado el anterior en la clase "News".
package com.manager.entities;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import com.manager.types.NewsState;
public class News implements Serializable{
/**
*
*/
private static final long serialVersionUID = 2102522851404135715L;
private String newsId;
private NewsState newsState;
private Calendar dateCreate;
private Calendar dateUpdate;
private Calendar dateDelete;
public News(String newsId) {
this(newsId, NewsState.RELEASED);
}
public News(String newsId, NewsState newsState) {
this(newsId, newsState, Calendar.getInstance(), Calendar.getInstance(), Calendar.getInstance());
}
public News(String newsId, NewsState newsState, Calendar dateCreate,
Calendar dateUpdate, Calendar dateDelete) {
this.newsId = newsId;
this.newsState = newsState;
this.dateCreate = dateCreate;
this.dateUpdate = dateUpdate;
this.dateDelete = dateDelete;
}
public String getNewsId() {
return newsId;
}
public void setNewsId(String newsId) {
this.newsId = newsId;
}
public NewsState getNewsState() {
return newsState;
}
public void setNewsState(NewsState newsState) {
this.newsState = newsState;
}
public Date getDateCreate() {
return dateCreate.getTime();
}
public void setDateCreate(Date dateCreate) {
this.dateCreate.setTime(dateCreate);
}
public Date getDateUpdate() {
return dateUpdate.getTime();
}
public void setDateUpdate(Date dateUpdate) {
this.dateUpdate.setTime(dateUpdate);
}
public Date getDateDelete() {
return dateDelete.getTime();
}
public void setDateDelete(Date dateDelete) {
this.dateDelete.setTime(dateDelete);
}
}
Y lo he asociado todo en el fichero news.hbm.xml.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.manager.entities">
<class name="News" table="news" schema="manager">
<id name="newsId" column="news_id" type="string" length="15" unsaved-value="null">
<generator class="assigned" />
</id>
<property name="newsState" column="news_state" not-null="true">
<type name="com.manager.types.GenericEnumUserType">
<param name="enumClass">com.manager.types.NewsState</param>
</type>
</property>
<property name="dateCreate" column="news_date_create" type="timestamp"/>
<property name="dateUpdate" column="news_date_update" type="timestamp"/>
<property name="dateDelete" column="news_date_delete" type="timestamp"/>
</class>
</hibernate-mapping>
Por último os muestro la tabla news de la base de datos:
package com.manager.types;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.type.NullableType;
import org.hibernate.type.TypeFactory;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
import org.jboss.logging.Logger;
public class GenericEnumUserType implements UserType, ParameterizedType {
private static final Logger log = Logger.getLogger(GenericEnumUserType.class);
private static final String DEFAULT_IDENTIFIER_METHOD_NAME = "name";
private static final String DEFAULT_VALUE_OF_METHOD_NAME = "valueOf";
private Class<? extends Enum> enumClass;
private Class<?> identifierType;
private Method identifierMethod;
private Method valueOfMethod;
private NullableType type;
private int[] sqlTypes;
public void setParameterValues(Properties parameters) {
String enumClassName = parameters.getProperty("enumClass");
try {
enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
} catch (ClassNotFoundException cfne) {
throw new HibernateException("Enum class not found", cfne);
}
String identifierMethodName = parameters.getProperty("identifierMethod", DEFAULT_IDENTIFIER_METHOD_NAME);
try {
identifierMethod = enumClass.getMethod(identifierMethodName, new Class[0]);
identifierType = identifierMethod.getReturnType();
} catch (Exception e) {
throw new HibernateException("Failed to obtain identifier method", e);
}
type = (NullableType) TypeFactory.basic(identifierType.getName());
if (type == null)
throw new HibernateException("Unsupported identifier type " + identifierType.getName());
sqlTypes = new int[] { type.sqlType() };
String valueOfMethodName = parameters.getProperty("valueOfMethod", DEFAULT_VALUE_OF_METHOD_NAME);
try {
valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[] { identifierType });
} catch (Exception e) {
throw new HibernateException("Failed to obtain valueOf method", e);
}
}
public Class returnedClass() {
return enumClass;
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
Object identifier = type.get(rs, names[0]);
if (rs.wasNull()) {
return null;
}
try {
return valueOfMethod.invoke(enumClass, new Object[] { identifier });
} catch (Exception e) {
throw new HibernateException("Exception while invoking valueOf method '" + valueOfMethod.getName() + "' of " +
"enumeration class '" + enumClass + "'", e);
}
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
try {
if (value == null) {
st.setNull(index, type.sqlType());
} else {
Object identifier = identifierMethod.invoke(value, new Object[0]);
type.set(st, identifier, index);
}
} catch (Exception e) {
throw new HibernateException("Exception while invoking identifierMethod '" + identifierMethod.getName() + "' of " +
"enumeration class '" + enumClass + "'", e);
}
}
public int[] sqlTypes() {
return sqlTypes;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public boolean equals(Object x, Object y) throws HibernateException {
return x == y;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public boolean isMutable() {
return false;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
Después he creado la clase enumerada "NewsState" que quería que se mapeara con su correspondiente tipo en la base de datos. Esta clase la he tenido que crear en su propio fichero .java sino no me funcionaba.
package com.manager.types;
public enum NewsState {
RELEASED,
NO_RELEASED,
DELETE
}
Una vez creado los tipos, he utilizado el anterior en la clase "News".
package com.manager.entities;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import com.manager.types.NewsState;
public class News implements Serializable{
/**
*
*/
private static final long serialVersionUID = 2102522851404135715L;
private String newsId;
private NewsState newsState;
private Calendar dateCreate;
private Calendar dateUpdate;
private Calendar dateDelete;
public News(String newsId) {
this(newsId, NewsState.RELEASED);
}
public News(String newsId, NewsState newsState) {
this(newsId, newsState, Calendar.getInstance(), Calendar.getInstance(), Calendar.getInstance());
}
public News(String newsId, NewsState newsState, Calendar dateCreate,
Calendar dateUpdate, Calendar dateDelete) {
this.newsId = newsId;
this.newsState = newsState;
this.dateCreate = dateCreate;
this.dateUpdate = dateUpdate;
this.dateDelete = dateDelete;
}
public String getNewsId() {
return newsId;
}
public void setNewsId(String newsId) {
this.newsId = newsId;
}
public NewsState getNewsState() {
return newsState;
}
public void setNewsState(NewsState newsState) {
this.newsState = newsState;
}
public Date getDateCreate() {
return dateCreate.getTime();
}
public void setDateCreate(Date dateCreate) {
this.dateCreate.setTime(dateCreate);
}
public Date getDateUpdate() {
return dateUpdate.getTime();
}
public void setDateUpdate(Date dateUpdate) {
this.dateUpdate.setTime(dateUpdate);
}
public Date getDateDelete() {
return dateDelete.getTime();
}
public void setDateDelete(Date dateDelete) {
this.dateDelete.setTime(dateDelete);
}
}
Y lo he asociado todo en el fichero news.hbm.xml.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.manager.entities">
<class name="News" table="news" schema="manager">
<id name="newsId" column="news_id" type="string" length="15" unsaved-value="null">
<generator class="assigned" />
</id>
<property name="newsState" column="news_state" not-null="true">
<type name="com.manager.types.GenericEnumUserType">
<param name="enumClass">com.manager.types.NewsState</param>
</type>
</property>
<property name="dateCreate" column="news_date_create" type="timestamp"/>
<property name="dateUpdate" column="news_date_update" type="timestamp"/>
<property name="dateDelete" column="news_date_delete" type="timestamp"/>
</class>
</hibernate-mapping>
Por último os muestro la tabla news de la base de datos:
Configuracion Hibernate en Spring
Para configurar hibernate en Spring he tenido que hacer los siguiente:
Crear mi propio filtro, que lo he llamado CustomHibernateSessionFilter. Este filtro es necesario para establecer el FlushMode a AUTO y sobreescribir el de defecto (FlushMode.NEVER) que me ha dado problemas como la excepción que he puesto más abajo.
package com.manager.filters;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;
public class CustomHibernateSessionFilter extends OpenSessionInViewFilter {
protected Session getSession(SessionFactory sessionFactory)
throws DataAccessResourceFailureException {
Session session = super.getSession(sessionFactory);
session.setFlushMode(FlushMode.AUTO);
return session;
}
protected void closeSession(Session session, SessionFactory factory) {
session.flush();
super.closeSession(session, factory);
}
}
Después, en el archivo web.xml he he creado también el filtro:
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>com.manager.filters.CustomHibernateSessionFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Tiene que haber una forma más fácil pero por el momento crear mi propio filtro extendiendio del que nos proporciona Spring me ha resuelto algunos problemas con la gestión de la sesión, en concreto me daba esta excepción:"Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition." y la fuente de la solución la encontre en este link: https://forum.hibernate.org/viewtopic.php?f=1&t=1007587&view=next. Si averiguo una forma más fácil lo añadiré al final de la entrada.
Esta es la implementación del dao que utilizo para obtener las entidades de la base de datos:
package com.manager.dao;
import java.io.Serializable;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
@Repository
public class SpringHibernateDAO extends HibernateDaoSupport implements IGenericDAO {
@Autowired
public SpringHibernateDAO(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
public void persist(Object entity) {
getHibernateTemplate().saveOrUpdate(entity);
}
public void persist(Object[] entities) {
for (int i = 0; i < entities.length; i++) {
persist(entities[i]);
}
}
public <T> List<T> find(Class<T> entityClass) {
final List<T> entities = getHibernateTemplate().loadAll(entityClass);
return entities;
}
public <T> T load(Class<T> entityClass, Serializable id) {
final T entity = (T) getHibernateTemplate().load(entityClass, id);
return entity;
}
public <T> List<T> find(String hql) {
final List<T> entities = getHibernateTemplate().find(hql);
return entities;
}
}
Y esta la interfaz:
package com.manager.dao;
import java.io.Serializable;
import java.util.List;
public interface IGenericDAO {
public void persist(Object entity);
public void persist(Object[] entities);
public <T> List<T> find(Class<T> entityClass);
public <T> T load(Class<T> entityClass, Serializable id);
public <T> List<T> find(String hql);
}
Y el servicio que utiliza el repositorio es el siguiente:
package com.manager.services;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.manager.dao.IGenericDAO;
import com.manager.entities.Module;
@Service
public class ModuleService {
@Resource
private IGenericDAO dao;
public Module newModule() {
return new Module();
}
public void persist(Object obj) {
dao.persist(obj);
}
public List<Module> getModules() {
final List<Module> list = dao.find(Module.class);
return list;
}
public Module getModule(int moduleId){
return dao.load(Module.class, moduleId);
}
}
El fichero con la configuración de hibernate es el siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<aop:aspectj-autoproxy />
<tx:annotation-driven transaction-manager="transacctionManager"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="15" />
<property name="maxActive" value="30" />
<property name="maxIdle" value="10" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!--<property name="configLocation" value="classpath:hibernate.cfg.xml" /> -->
<property name="dataSource" ref="dataSource"/>
<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
<property name="mappingResources">
<list>
<value>news.hbm.xml</value>
<value>module.hbm.xml</value>
<value>newspaper.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.query.substitutions">true 'T', false 'F'</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.c3p0.minPoolSize">5</prop>
<prop key="hibernate.c3p0.maxPoolSize">20</prop>
<prop key="hibernate.c3p0.timeout">600</prop>
<prop key="hibernate.c3p0.max_statement">50</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
<prop key="hibernate.transaction.factory_class">org.springframework.orm.hibernate3.SpringTransactionFactory</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
<!--
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
</bean>
-->
<!--
<bean id="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
<property name="flushModeName">
<value>FLUSH_AUTO</value>
</property>
</bean>
-->
<!--
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="hibInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Un fichero de hibernate que he añadido es el module.hbm.xml, cuyo código es el siguiente:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.manager.entities">
<class name="Module" table="modules" schema="manager">
<id name="moduleId" column="module_id" type="integer" unsaved-value="null">
<generator class="increment" />
</id>
<property name="name" column="modules_name" type="string"/>
</class>
</hibernate-mapping>
Es muy simple. Lo que hacemos es decirle el paquete donde esta creada la entidad, la clase que utilizamos (Módule) y que se mapeará con la columna de la tabla de base de datos "modules". Esta clase tiene un atributo "moduleId" que se corresponde con la columna "module_id" de la base de datos de tipo "integer" y no puede ser nula y cuyo identificador al crearse se debe autoincrementar, y también tiene otra propiedad "name".
Una vez tenemos todo lo anterior. Podemos incluir el servicio en un controlador y crear las entidades correspondientes en la base de datos. Por ejemplo yo me he creado el siguiente controlador.
package com.manager.controllers;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.manager.entities.Module;
import com.manager.services.ModuleService;
@Controller
@RequestMapping("/module")
public class ModuleController {
protected static final Logger logger = Logger.getLogger(ModuleController.class);
@Resource
private ModuleService mModule;
@ModelAttribute("module")
public Module populateForm() {
return new Module(); // creamos el bean para que se pueda popular
}
@RequestMapping(value="/form", method=RequestMethod.GET)
public String formView() {
return "fmodule";
}
@RequestMapping(value="/form/join", method=RequestMethod.GET)
public String formJoinView() {
return "fmoduleJoin";
}
@RequestMapping(value="/{moduleId}", method=RequestMethod.GET)
public @ResponseBody Object findModule(@PathVariable String moduleId, Model model) {
return mModule.getModule(Integer.valueOf(moduleId));
}
@RequestMapping(value="/list", method=RequestMethod.POST)
public @ResponseBody List<Module> getAllModules(Model model) {
return mModule.getModules();
}
@RequestMapping(value="/new", method=RequestMethod.POST)
public @ResponseBody Module createModule(@RequestBody Module module, Model model) {
mModule.persist(module);
return module;
}
}
Crear mi propio filtro, que lo he llamado CustomHibernateSessionFilter. Este filtro es necesario para establecer el FlushMode a AUTO y sobreescribir el de defecto (FlushMode.NEVER) que me ha dado problemas como la excepción que he puesto más abajo.
package com.manager.filters;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;
public class CustomHibernateSessionFilter extends OpenSessionInViewFilter {
protected Session getSession(SessionFactory sessionFactory)
throws DataAccessResourceFailureException {
Session session = super.getSession(sessionFactory);
session.setFlushMode(FlushMode.AUTO);
return session;
}
protected void closeSession(Session session, SessionFactory factory) {
session.flush();
super.closeSession(session, factory);
}
}
Después, en el archivo web.xml he he creado también el filtro:
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>com.manager.filters.CustomHibernateSessionFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Tiene que haber una forma más fácil pero por el momento crear mi propio filtro extendiendio del que nos proporciona Spring me ha resuelto algunos problemas con la gestión de la sesión, en concreto me daba esta excepción:"Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition." y la fuente de la solución la encontre en este link: https://forum.hibernate.org/viewtopic.php?f=1&t=1007587&view=next. Si averiguo una forma más fácil lo añadiré al final de la entrada.
Esta es la implementación del dao que utilizo para obtener las entidades de la base de datos:
package com.manager.dao;
import java.io.Serializable;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
@Repository
public class SpringHibernateDAO extends HibernateDaoSupport implements IGenericDAO {
@Autowired
public SpringHibernateDAO(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
public void persist(Object entity) {
getHibernateTemplate().saveOrUpdate(entity);
}
public void persist(Object[] entities) {
for (int i = 0; i < entities.length; i++) {
persist(entities[i]);
}
}
public <T> List<T> find(Class<T> entityClass) {
final List<T> entities = getHibernateTemplate().loadAll(entityClass);
return entities;
}
public <T> T load(Class<T> entityClass, Serializable id) {
final T entity = (T) getHibernateTemplate().load(entityClass, id);
return entity;
}
public <T> List<T> find(String hql) {
final List<T> entities = getHibernateTemplate().find(hql);
return entities;
}
}
Y esta la interfaz:
package com.manager.dao;
import java.io.Serializable;
import java.util.List;
public interface IGenericDAO {
public void persist(Object entity);
public void persist(Object[] entities);
public <T> List<T> find(Class<T> entityClass);
public <T> T load(Class<T> entityClass, Serializable id);
public <T> List<T> find(String hql);
}
Y el servicio que utiliza el repositorio es el siguiente:
package com.manager.services;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.manager.dao.IGenericDAO;
import com.manager.entities.Module;
@Service
public class ModuleService {
@Resource
private IGenericDAO dao;
public Module newModule() {
return new Module();
}
public void persist(Object obj) {
dao.persist(obj);
}
public List<Module> getModules() {
final List<Module> list = dao.find(Module.class);
return list;
}
public Module getModule(int moduleId){
return dao.load(Module.class, moduleId);
}
}
El fichero con la configuración de hibernate es el siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<aop:aspectj-autoproxy />
<tx:annotation-driven transaction-manager="transacctionManager"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="15" />
<property name="maxActive" value="30" />
<property name="maxIdle" value="10" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!--<property name="configLocation" value="classpath:hibernate.cfg.xml" /> -->
<property name="dataSource" ref="dataSource"/>
<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
<property name="mappingResources">
<list>
<value>news.hbm.xml</value>
<value>module.hbm.xml</value>
<value>newspaper.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.query.substitutions">true 'T', false 'F'</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.c3p0.minPoolSize">5</prop>
<prop key="hibernate.c3p0.maxPoolSize">20</prop>
<prop key="hibernate.c3p0.timeout">600</prop>
<prop key="hibernate.c3p0.max_statement">50</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
<prop key="hibernate.transaction.factory_class">org.springframework.orm.hibernate3.SpringTransactionFactory</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
<!--
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
</bean>
-->
<!--
<bean id="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
<property name="flushModeName">
<value>FLUSH_AUTO</value>
</property>
</bean>
-->
<!--
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="hibInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Un fichero de hibernate que he añadido es el module.hbm.xml, cuyo código es el siguiente:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.manager.entities">
<class name="Module" table="modules" schema="manager">
<id name="moduleId" column="module_id" type="integer" unsaved-value="null">
<generator class="increment" />
</id>
<property name="name" column="modules_name" type="string"/>
</class>
</hibernate-mapping>
Es muy simple. Lo que hacemos es decirle el paquete donde esta creada la entidad, la clase que utilizamos (Módule) y que se mapeará con la columna de la tabla de base de datos "modules". Esta clase tiene un atributo "moduleId" que se corresponde con la columna "module_id" de la base de datos de tipo "integer" y no puede ser nula y cuyo identificador al crearse se debe autoincrementar, y también tiene otra propiedad "name".
Una vez tenemos todo lo anterior. Podemos incluir el servicio en un controlador y crear las entidades correspondientes en la base de datos. Por ejemplo yo me he creado el siguiente controlador.
package com.manager.controllers;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.manager.entities.Module;
import com.manager.services.ModuleService;
@Controller
@RequestMapping("/module")
public class ModuleController {
protected static final Logger logger = Logger.getLogger(ModuleController.class);
@Resource
private ModuleService mModule;
@ModelAttribute("module")
public Module populateForm() {
return new Module(); // creamos el bean para que se pueda popular
}
@RequestMapping(value="/form", method=RequestMethod.GET)
public String formView() {
return "fmodule";
}
@RequestMapping(value="/form/join", method=RequestMethod.GET)
public String formJoinView() {
return "fmoduleJoin";
}
@RequestMapping(value="/{moduleId}", method=RequestMethod.GET)
public @ResponseBody Object findModule(@PathVariable String moduleId, Model model) {
return mModule.getModule(Integer.valueOf(moduleId));
}
@RequestMapping(value="/list", method=RequestMethod.POST)
public @ResponseBody List<Module> getAllModules(Model model) {
return mModule.getModules();
}
@RequestMapping(value="/new", method=RequestMethod.POST)
public @ResponseBody Module createModule(@RequestBody Module module, Model model) {
mModule.persist(module);
return module;
}
}
sábado, 7 de enero de 2012
Configuración proyecto Spring
En la carpeta lib añadimos todas las librerias que necesitamos para que funcione Spring, como el proyecto lo tengo avanzado en estos momentos, tengo muchas librerias más a parte, para el funcionamiento de hibernate, seguridad de Spring, etc.

Las que tienen el guión al final son las que no he utilizado por el momento.
En el fichero web.xml tengo lo siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/configuration/applicationContext-security.xml
/WEB-INF/configuration/applicationContext-business.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/properties/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlets/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
<display-name>SpringWeb</display-name>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
En contextConfigLocation tengo la configuración de Spring junto con la seguridad.
He declarado el servlet spring y le he establecido la ruta donde se encuentra su archivo de configuración. Automáticamente Spring detecta el archivo servlet-spring.xml dentro de /WEB-INF/ si no se le estable la configuración de esta manera.
También le he añadido el filtro springSecurityFilterChain que es necesario si se quiere utilizar la capa de seguridad de Spring. Para mí es necesario conocer esto al dedillo.
En el fichero de configuración applicationContext-business.xml tengo lo siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<aop:aspectj-autoproxy />
<tx:annotation-driven transaction-manager="transacctionManager"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="15" />
<property name="maxActive" value="30" />
<property name="maxIdle" value="10" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!--<property name="configLocation" value="classpath:hibernate.cfg.xml" /> -->
<property name="dataSource" ref="dataSource"/>
<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
<property name="mappingResources">
<list>
<value>news.hbm.xml</value>
<value>module.hbm.xml</value>
<value>newspaper.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.query.substitutions">true 'T', false 'F'</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.c3p0.minPoolSize">5</prop>
<prop key="hibernate.c3p0.maxPoolSize">20</prop>
<prop key="hibernate.c3p0.timeout">600</prop>
<prop key="hibernate.c3p0.max_statement">50</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
<prop key="hibernate.transaction.factory_class">org.springframework.orm.hibernate3.SpringTransactionFactory</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="hibInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
Con esto tendríamos la capa de persistencia.
Como se puede ver he añadido los siguiente ficheros de hibernate para mapear clases a tablas de bd. Estos ficheros tienen que estar dentro de la carpeta "resources" que dije que crearamos al principio para que cuando se compile el proyecto se copien en el classpath.
classpath:database.properties
<value>news.hbm.xml</value>
<value>module.hbm.xml</value>
<value>newspaper.hbm.xml</value>
Por ejemplo en mi caso queda así:

Las que tienen el guión al final son las que no he utilizado por el momento.
En el fichero web.xml tengo lo siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/configuration/applicationContext-security.xml
/WEB-INF/configuration/applicationContext-business.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/properties/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlets/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
<display-name>SpringWeb</display-name>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
En contextConfigLocation tengo la configuración de Spring junto con la seguridad.
He declarado el servlet spring y le he establecido la ruta donde se encuentra su archivo de configuración. Automáticamente Spring detecta el archivo servlet-spring.xml dentro de /WEB-INF/ si no se le estable la configuración de esta manera.
También le he añadido el filtro springSecurityFilterChain que es necesario si se quiere utilizar la capa de seguridad de Spring. Para mí es necesario conocer esto al dedillo.
En el fichero de configuración applicationContext-business.xml tengo lo siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<aop:aspectj-autoproxy />
<tx:annotation-driven transaction-manager="transacctionManager"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="15" />
<property name="maxActive" value="30" />
<property name="maxIdle" value="10" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!--<property name="configLocation" value="classpath:hibernate.cfg.xml" /> -->
<property name="dataSource" ref="dataSource"/>
<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
<property name="mappingResources">
<list>
<value>news.hbm.xml</value>
<value>module.hbm.xml</value>
<value>newspaper.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.query.substitutions">true 'T', false 'F'</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.c3p0.minPoolSize">5</prop>
<prop key="hibernate.c3p0.maxPoolSize">20</prop>
<prop key="hibernate.c3p0.timeout">600</prop>
<prop key="hibernate.c3p0.max_statement">50</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
<prop key="hibernate.transaction.factory_class">org.springframework.orm.hibernate3.SpringTransactionFactory</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="hibInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
Con esto tendríamos la capa de persistencia.
Como se puede ver he añadido los siguiente ficheros de hibernate para mapear clases a tablas de bd. Estos ficheros tienen que estar dentro de la carpeta "resources" que dije que crearamos al principio para que cuando se compile el proyecto se copien en el classpath.
classpath:database.properties
<value>news.hbm.xml</value>
<value>module.hbm.xml</value>
<value>newspaper.hbm.xml</value>
Por ejemplo en mi caso queda así:
Suscribirse a:
Entradas (Atom)