Je migre une application de la configuration hibernate xml vers des annotations, je ne sais pas comment adapter ma classe BusinessObjectInterceptor au nouveau format basé sur les annotations.Intercepteurs Hibernate avec annotations
Nous changeons notre classe HibernateUtil de créer SessionFactory
InitialContext ctx = new InitialContext();
sessionFactory = (SessionFactory)ctx.lookup("java:/hibernate/SessionFactory");
à la création EntityManagerFactory
entityManagerFactory = Persistence.createEntityManagerFactory("primary");
Nous changeons notre classe HibernateUtil d'utiliser sessionFactory.openSession() pour la création d'une session à partir d'un EntityManager
//s = sessionFactory.openSession(new BusinessObjectInterceptor());
EntityManager entityManager = entityManagerFactory.createEntityManager();
s = entityManager.unwrap(Session.class);
Le problème i s Je ne suis pas sûr de savoir comment injecter un BusinessObjectInterceptor dans une nouvelle Session Hibernate, ou la bonne façon d'annoter mes classes pour qu'elles puissent utiliser l'Interceptor
J'essaie de définir l'Interceptor comme une propriété dans la persistance. xml. Je ne sais pas si cela est correct
<?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>
Nos cours ont déjà été configurés via des fichiers 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>
les classes annotées ressemblent
@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;
Nous avons une classe BusinessObjectInterceptor et une classe BusinessObject. Je les posterai ci-dessous pour référence. Je pense que ce qui doit arriver est que la classe BusinessObject doit être annotée, je ne sais pas comment cela se fait puisque BusinessObject ne correspond pas aux colonnes d'une table spécifique, mais plutôt aux colonnes communes à toutes les tables de notre base de données. Je vais coller ces deux classes ci-dessous. Tout conseil sur comment configurer mon Interceptor avec des annotations serait apprécié. Merci.
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;
}
double possible de [utiliser les annotations de printemps pour appliquer automatiquement Hibernate Interceptor?] (http://stackoverflow.com/questions/2132151/use-spring-annotations-to-automatically-apply-hibernate-interceptor) –
Il pourrait y avoir être une information dans ce q Cela pourrait m'aider, mais je n'utilise pas Spring, donc ce n'est pas entièrement applicable. – user619804
Ok.Je ne peux pas rétracter mon vote serré, mais s'il se termine, je voterai pour repoen. –