Estoy migrando una aplicación de configuración hibernate xml a anotaciones, no estoy seguro de cómo adaptar mi clase BusinessObjectInterceptor al nuevo formato basado en anotaciones.Interceptores Hibernate con anotaciones
Estamos cambiando nuestra clase HibernateUtil desde la creación de SessionFactory
InitialContext ctx = new InitialContext();
sessionFactory = (SessionFactory)ctx.lookup("java:/hibernate/SessionFactory");
a la creación de EntityManagerFactory
entityManagerFactory = Persistence.createEntityManagerFactory("primary");
Estamos cambiando nuestra clase HibernateUtil el uso de sessionFactory.openSession() para crear una sesión de un EntityManager
//s = sessionFactory.openSession(new BusinessObjectInterceptor());
EntityManager entityManager = entityManagerFactory.createEntityManager();
s = entityManager.unwrap(Session.class);
El problema que s No estoy seguro de cómo inyectar un BusinessObjectInterceptor en una nueva sesión de Hibernate, o la forma correcta de anotar mis clases para que puedan usar el Interceptor
Estoy tratando de configurar el Interceptor como una propiedad en persistencia. xml. No estoy seguro de si esto es correcto
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="primary"><jta-data-source>java:jboss/datasources/MySqlDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.ejb.interceptor.session_scoped" value="com.mycompany.common.persistence.BusinessObjectInterceptor"/>
</properties>
Nuestras clases se han configurado previamente a través de archivos hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.mycompany.liveexpert.common.businessobjects.ServerSettings" table="server_settings">
<id name="serverSettingsID" type="integer" column="server_settings_id">
<generator class="identity" />
</id>
<version name="updateCounter" column="update_counter"/>
<property name="changedDate" type="timestamp" column="changed_date"/>
<property name="changedBy" type="string" column="changed_by"/>
<property name="createdDate" type="timestamp" column="created_date"/>
<property name="createdBy" type="string" column="created_by"/>
<property name="status" type="string" column="status"/>
<property name="emailServer" type="string" column="email_server" />
<property name="emailFromAddress" type="string" column="email_from_address" />
<property name="emailUser" type="string" column="email_user" />
<property name="emailPassword" type="string" column="email_password" />
</class>
las clases anotadas parecen
@Entity
@Table(name="server_settings")
public class ServerSettings extends BusinessObject
{
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer serverSettingsID;
@Column(name = "email_server")
private String emailServer;
@Column(name = "email_from_address")
private String emailFromAddress;
@Column(name = "email_user")
private String emailUser;
@Column(name = "email_password")
private String emailPassword;
Tenemos una clase BusinessObjectInterceptor y una clase BusinessObject. Los publicaré a continuación como referencia. Creo que lo que debe suceder es que la clase BusinessObject necesite ser anotada, no estoy seguro de cómo se hace, ya que BusinessObject no se correlaciona con columnas en una tabla específica, sino más bien con columnas que son comunes a todas las tablas en nuestra base de datos. Pegaré estas dos clases a continuación. Cualquier consejo sobre cómo configurar mi Interceptor con anotaciones sería apreciado. Gracias.
BusinessObjectInterceptor
public class BusinessObjectInterceptor extends EmptyInterceptor
{
private int updates;
private int creates;
private static final String defaultDesignation = "system";
private String getUserDesignation()
{
UserContextI theContext = PersistenceContext.getUserContext();
if (theContext == null) return defaultDesignation;
String uid = theContext.getUserDesignation();
if (uid == null) return defaultDesignation;
return uid;
}
public boolean onFlushDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types)
{
boolean theReturn = false;
if (entity instanceof BusinessObject)
{
updates++;
for (int i=0; i<propertyNames.length; i++)
{
if ("changedDate".equals(propertyNames[i]))
{
currentState[i] = new Date();
theReturn = true;
}
if ("changedBy".equals(propertyNames[i]))
{
currentState[i] = getUserDesignation();
theReturn = true;
}
}
}
return theReturn;
}
public boolean onSave(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types)
{
boolean theReturn = false;
if (entity instanceof BusinessObject)
{
creates++;
for (int i=0; i<propertyNames.length; i++)
{
if ("createdDate".equals(propertyNames[i]))
{
state[i] = new Date();
theReturn = true;
}
if ("createdBy".equals(propertyNames[i]))
{
state[i] = getUserDesignation();
theReturn = true;
}
if ("changedDate".equals(propertyNames[i]))
{
state[i] = new Date();
theReturn = true;
}
if ("changedBy".equals(propertyNames[i]))
{
state[i] = getUserDesignation();
theReturn = true;
}
}
}
return theReturn;
}
public void preFlush(Iterator entities)
{
updates = 0;
creates = 0;
}
BusinessObject
public abstract class BusinessObject
{
private String status;
private String createdBy;
private Date createdDate;
private String changedBy;
private Date changedDate;
private int updateCounter;
/**
* Generic save method to be used for persisting a business object.
*
* @return a copy of this business object in its saved state.
*
* @throws Exception
*/
public BusinessObject save() throws Exception
{
Session hsession = null;
Transaction tx = null;
BusinessObject theObject = null;
validate(); // throws ValidationException
try {
hsession = HibernateUtil.currentSession();
tx = hsession.beginTransaction();
if (getStatus() == null || getStatus().length() < 1)
{
setStatus("OK");
}
//theObject = (BusinessObject) hsession.saveOrUpdateCopy(this);
theObject = (BusinessObject) hsession.merge(this);
if (tx != null && tx.isActive() && !tx.wasCommitted())
tx.commit();
} catch (Exception e){
try
{
if (tx!=null) tx.rollback();
} catch (Exception e3)
{}
try
{
hsession.close();
} catch (Exception e2)
{}
throw e;
} finally
{
HibernateUtil.closeSession();
}
return theObject;
}
posible duplicado de anotaciones [uso de la primavera para aplicar automáticamente Hibernate Interceptor?] (http://stackoverflow.com/questions/2132151/use-spring-annotations-to-automatically-apply-hibernate-interceptor) –
podría ser alguna información en eso q Pregunta que me puede ayudar, pero no estoy usando Spring, así que no es del todo aplicable. – user619804
Ok.No puedo retractarme de mi voto cercano, pero si se cierra, votaré para volver a citar. –