Hello All,
Trying to fix an application that uses Event Listeners in Hibernate.
Table A, Table BThere is a dependency between these two, but we are not using hibernate to manage it.
b1 in B is created when a record a1 in A is created. And when there is a update to a1 there is a new entry b2 in B.As of now when a1 is created, b1 is also created. BUT when a1 is update b2 is not created.
And interesting point is I dont see any sql error or java error messages in the Log. After banging my head for a week, realized that when a1 is updated, the primary key is not being populated for b2 to be properly saved.
Is there anybody who have faced this problem earlier.
Please help me :)
Even if you can direct me to a resource which is similar to the code shown below, I can try few thing and figure it out myself.
Thank you for your time.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${jndi.datasource.prefix}${jndi.datasource}"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/jpa-persistence.xml" />
<property name="persistenceUnitName" value="${project.name}" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${hibernate.dialect}"/>
<property name="showSql" value="${hibernate.show_sql}" />
<property name="generateDdl" value="${hibernate.show_sql}" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.connection.datasource">${jndi.datasource.prefix}${jndi.datasource}</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.SingletonEhCacheProvider</prop>
<prop key="hibernate.connection.release_mode">on_close</prop>
[b]<prop key="hibernate.ejb.event.pre-insert">....DatabaseOperationListener </prop>
<prop key="hibernate.ejb.event.pre-update">......DatabaseOperationListener </prop>
<prop key="hibernate.ejb.event.pre-delete">......DatabaseOperationListener </prop>
[/b]
<prop key="hibernate.c3p0.validate">true</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">100</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
</props>
</property>
</bean>
</beans>
==================
public class DatabaseOperationListener implements PreDeleteEventListener, PreInsertEventListener, PreUpdateEventListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger("DatabaseOperationListener");
/**
*
*/
public DatabaseOperationListener()
{
}
/**
* @see org.hibernate.event.spi.PreDeleteEventListener#onPreDelete(org.hibernate.event.spi.PreDeleteEvent)
*/
@Transactional(propagation=Propagation.REQUIRED, rollbackFor={Throwable.class})
public boolean onPreDelete(PreDeleteEvent event)
{
this.logChange(event);
return false;
}
/**
* @see org.hibernate.event.spi.PreInsertEventListener#onPreInsert(org.hibernate.event.spi.PreInsertEvent)
*/
[b] @Transactional(propagation=Propagation.REQUIRES_NEW, rollbackFor={Throwable.class})
[/b] public boolean onPreInsert(PreInsertEvent event)
{
this.logChange(event);
return false;
}
/**
* @see org.hibernate.event.spi.PreUpdateEventListener#onPreUpdate(org.hibernate.event.spi.PreUpdateEvent)
*/
[b] @Transactional(propagation=Propagation.REQUIRES_NEW, rollbackFor={Throwable.class})
[/b] public boolean onPreUpdate(PreUpdateEvent event)
{
this.logChange(event);
return false;
}
/**
*
* @param event
*/
protected void logChange(PreInsertEvent event)
{
if(event.getEntity() instanceof Traceable)
{
Traceable t = (Traceable)event.getEntity();
t.setCreatedDate(new Timestamp(new Date().getTime()));
t.setLastUpdDate(t.getCreatedDate());
if(SecurityContextHolder.getContext().getAuthentication() != null)
{
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principal instanceof UserDetails)
{
UserDetails user = (UserDetails)principal;
t.setCreatorId(user.getUsername());
t.setLastUpdId(t.getCreatorId());
}
}
try
{
[b]synchronized(event.getState())
{
t.trace(event, this.createXmlContent(event.getEntity(), event.getPersister(), event.getState(), EventType.CREATE));
}[/b]
}
catch(Throwable ex)
{
logger.error("Unable to log PreInsertEvent for " + t, ex);
}
}
}
/**
*
* @param event
*/
protected void logChange(PreUpdateEvent event)
{
if(event.getEntity() instanceof Traceable)
{
Traceable t = (Traceable)event.getEntity();
t.setLastUpdDate(new Timestamp(new Date().getTime()));
if(SecurityContextHolder.getContext().getAuthentication() != null)
{
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principal instanceof UserDetails)
{
UserDetails user = (UserDetails)principal;
t.setLastUpdId(user.getUsername());
}
}
try
{
[b]synchronized(event.getOldState())
{
t.trace(event, this.createXmlContent(event.getEntity(), event.getPersister(), event.getOldState(), EventType.UPDATE));
}[/b]
}
catch(Throwable ex)
{
logger.error("Unable to log PreUpdateEvent for " + t, ex);
}
}
}
/**
*
* @param event
*/
protected void logChange(PreDeleteEvent event)
{
if(event.getEntity() instanceof Traceable)
{
Traceable t = (Traceable)event.getEntity();
try
{
t.trace(event, this.createXmlContent(event.getEntity(), event.getPersister(), event.getDeletedState(), EventType.DELETE));
}
catch(Throwable ex)
{
logger.error("Unable to log PreDeleteEvent for " + t, ex);
}
}
}