Spring + hibernate 3 "No Hibernate Session bound to thread" But i have a transaction manager configured - spring

i have this problem: "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here". I'm using spring + hibernate 3. I already had checking this in other questions, but they donĀ“t solve my problem. Here, my applicationContext of Spring.
`<bean id="ServGenerico" class="servico.AbsServicoGenerico" />
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
p:driverClass="${jdbc.driver}" p:jdbcUrl="${jdbc.url}" p:user="${jdbc.username}"
p:password="${jdbc.password}" p:max PoolSize="10" p:minPoolSize="5" p:maxStatements="0" destroy-method="close">
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="dao" />
<context:component-scan base-package="dao.impl" />
<context:component-scan base-package="servico" />
<bean id="grupoDeAcaoDao" class="dao.impl.GrupoDeAcaoDao" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="dados" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- <prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</prop>
--><!-- <prop key="hibernate.c3p0.max_size">10</prop>
<prop key="hibernate.c3p0.min_size">2</prop>
<prop key="hibernate.c3p0.timeout">5000</prop>
<prop key="hibernate.c3p0.max_statements">10</prop>
<prop key="hibernate.c3p0.idle_test_period">3000</prop>
<prop key="hibernate.c3p0.acquire_increment">2</prop> -->
<!-- <prop key="hibernate.transaction.jta.platform">
org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform
</prop> -->
</props>
</property>
</bean>`
My service
#Service
#Transactional
public class ServGrupoDeAcao extends AbsServicoGenerico<GrupoDeAcao>
{
public ServGrupoDeAcao()
{
super();
setDao(new GrupoDeAcaoDao());
}
public ServGrupoDeAcao(Class<?> clazz)
{
super(clazz);
}
/*#Autowired
#Qualifier("grupoDeAcaoDao")
public void setDao(GrupoDeAcaoDao dao)
{
super.setDao(dao);
}*/
}
And my DAO
#Repository
#Transactional
public class GrupoDeAcaoDao extends AbsDao<GrupoDeAcao, Long>
{
#Override
public boolean equals(Object object)
{
// TODO Auto-generated method stub
return false;
}
#Override
public int hashCode()
{
// TODO Auto-generated method stub
return 0;
}
#Override
public Object executarConsultaPersonalizada(NomeMetodo nome,
Parametros parametros)
{
// TODO Auto-generated method stub
return null;
}
public boolean daoCompativel(Class<?> clazz)
{
return GrupoDeAcao.class.equals(clazz);
}
The class AbsDao is a generic class that have in your methods, save, update e etc.
And this class have the #Repository and #Transactional Anotations

Related

HibernateTemplate object is null while saving data using spring MVC+hibernate

I'm trying to insert data into table using Spring MVC+Hibernate. Table is geting creating but code throwing exception at template.save() method calling in CompanyDao file. Please help to solve this.
I have tested if company object is null but company object having all data but template in null.
File: CompanyDao.java
import org.springframework.orm.hibernate5.HibernateTemplate;
public class CompanyDao {
HibernateTemplate template;
public void setTemplate(HibernateTemplate template) {
this.template = template;
}
//method to save Company
public void saveCompany(Company c){
if(c!=null) {
template.save(c);
}
else {
System.out.print("company object is null");
}
}
}
ApplicationContext.xml
<bean id="mysessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mappingResources">
<list>
<value>company.hbm.xml</value>
<!-- <value>address.hbm.xml</value> -->
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="mysessionFactory"></property>
</bean>
<bean id="template" class="dao.CompanyDao">
<property name="template" ref="hibernateTemplate"></property>
</bean>
File Controller:
#RequestMapping("/submitCompanyRegForm")
public ModelAndView submitCompanyRegForm(#ModelAttribute("companyMo") Company comp)
{
CompanyDao companydao = new CompanyDao();
companydao.saveCompany(comp);
ModelAndView model = new ModelAndView("submitcompanyreg");
return model;
}

How to register a Hibernate Empty Interceptor in Spring's applicationContext.xml

How do I easily hook up a Hibernate EmptyInterceptor (an Audit Interceptor) in a Spring app's applicationContext.xml?
No annotations are supported, this is an older Spring app.
My Hibernate Empty Interceptor is
public class AuditInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = 1L;
#Override
public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
// TODO Auto-generated method stub
System.out.println("onDelete intercepted");
super.onDelete(entity, id, state, propertyNames, types);
}
#Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types) {
// TODO Auto-generated method stub
System.out.println("onFlushDirty intercepted");
return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
}
#Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
// TODO Auto-generated method stub
System.out.println("onSave intercepted");
return super.onSave(entity, id, state, propertyNames, types);
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${jdbc.datasource}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.c3p0.max_size">10</prop>
<prop key="hibernate.c3p0.min_size">1</prop>
<prop key="hibernate.c3p0.timeout">5000</prop>
<prop key="hibernate.c3p0.max_statements">100</prop>
<prop key="hibernate.c3p0.idle_test_period">300</prop>
<prop key="hibernate.c3p0.acquire_increment">2</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
The following worked. Thanks for the tip
<!-- First define the bean -->
<bean id="auditInterceptor" class="mypackage.AuditInterceptor" />
<!-- Now add entityInterceptor property in sessionFactory Bean, referring to this bean -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="entityInterceptor" ref="auditInterceptor" />

Spring Data JPA + Hibernate : Inject Catalog/Schema at runtime in to JPA Entities

We have a scenario where in the catalog/schema combination is different for the entity classes inside certain package from the default one used by all others. I am trying to set Catalog and Schema on #Table annotation using PersistenceUnitPostProcessors callback at runtime using javaassist as below.
The issue: The added member values on javaassist annotation are NOT getting reflected on to the actual class associated with it. Please help me in finding the wrong lines of code; OR if there are other ways to achieve this, more than happy to know.
Note: I do not want to create a separate EntityManagerFactory for each catalog/schema combination - it is not really required in our case as the datasource is same.
related content in spring context :
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven />
<bean name="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="mainUnit" />
<property name="packagesToScan" value="com.mycompany.lob.domain" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="persistenceUnitPostProcessors">
<list>
<bean class="com.mycompany.lob.jpa.CustomPersistenceUnitPostProcessor"/>
</list>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SqlmxDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.jdbc.batch_size">100</prop>
<prop key="hibernate.order_inserts">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.connection.autocommit">true</prop>
<prop key="hibernate.default_schema">DEFAULT_SCHEMA</prop>
<prop key="hibernate.default_catalog">DEFAULT_CATALOG</prop>
</props>
</property>
</bean>
PersistenceUnitPostProcessors callback :
public class CustomPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor {
#Value("${user.schema}")
private String userSchema;
#Value("${user.catalog}")
private String userCatalog;
private static final Logger LOGGER = LoggerFactory.getLogger(CustomPersistenceUnitPostProcessor.class);
#SuppressWarnings("unchecked")
#Override
public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
LOGGER.info("MutablePersistenceUnitInfo : {} ",pui);
List<String> jpadomains = pui.getManagedClassNames();
for (Iterator<?> iterator = jpadomains.iterator(); iterator.hasNext();) {
String clazzName = (String) iterator.next();
if(clazzName.startsWith("com.mycompany.lob.domain.user")){
try {
//modify annotation attributes using JavaAssist
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.get(clazzName);
ClassFile classFile = ctClass.getClassFile();
ConstPool constPool = classFile.getConstPool();
AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute)classFile.getAttribute(AnnotationsAttribute.visibleTag);
if(annotationsAttribute!=null){
//Get hold of #Table annotation
Annotation tableAnnotation = annotationsAttribute.getAnnotation("javax.persistence.Table");
if(tableAnnotation!=null){
tableAnnotation.addMemberValue("catalog", new StringMemberValue(userCatalog, constPool));
tableAnnotation.addMemberValue("schema", new StringMemberValue(userSchema, constPool));
annotationsAttribute.addAnnotation(tableAnnotation);
LOGGER.debug("Schema-Table : {} - {} ", ((StringMemberValue)tableAnnotation.getMemberValue("schema")).getValue(),
((StringMemberValue)tableAnnotation.getMemberValue("name")).getValue() );
//write the file back
ctClass.writeFile();
}
}
} catch (Exception e) {
LOGGER.error("Schema/Catalog could not be altered for {} ",clazzName);
}
}
}
}
}
Simple answer:
19. Multitenancy
Complex catalog mapping:
interface PhysicalNamingStrategy in Hibernate v5 is helpful.
public interface PhysicalNamingStrategy {
public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment);
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment);
....
}
Check the Example 2. Example PhysicalNamingStrategy implementation in Hibernate 5 User Guide and how to config it

Spring test does not roll back after test

I have a series of integration tests using Spring tests and a H2 memory database. I've noticed that the h2 database does not get rolled back after every test.
This is my config:
#RunWith(SpringJUnit4ClassRunner.class)
public class BlaServiceIntegrationTest extends AbstractTest {
#Autowired
private BlaService blaService;
#Test()
public void doBla() {
// some other test that writes in the database
}
#Test()
public void saveNewBla() {
assertEquals(0, findAllBlas().size()); // <-- fails, the db is not empty.
// the previous test did not roll back
}
Then there is the AbstractTest:
#ContextConfiguration(locations = { "classpath:test-with-db.xml" })
#TransactionConfiguration(defaultRollback = true)
#Transactional()
public class AbstractTest {
private static final Logger LOG = LoggerFactory.getLogger(AbstractTest.class);
#Autowired
protected SessionFactory sessionFactory;
public AbstractTest() {
super();
}
#SuppressWarnings("unchecked")
protected List<Bla> findAllBlas() {
return sessionFactory.getCurrentSession().createCriteria(Bla.class).list();
}
The Spring config:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource "
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}">
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl}</prop>
<!-- <prop key="hibernate.use_sql_comments">false</prop> -->
</props>
</property>
<property name="packagesToScan" value="com.company.bla.back.domain"></property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory">
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="hibernateConfiguration" factory-bean="&sessionFactory"
factory-method="getConfiguration" />
And the config.properties specific to the test:
################### MySQL JDBC Configuration ##################
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem;DB_CLOSE_ON_EXIT=FALSE
jdbc.username=
jdbc.password=
################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=false
hibernate.hbm2ddl=create-drop
hibernate.generate_statistics=false
And the service being tested:
#Service("blaService")
#Transactional(propagation = Propagation.MANDATORY)
public class BlaServiceImpl implements BlaService {
Never mind, I found the solution myself. It wasn't a rollback problem at all?
There was a mistake in my findAllBla() method? It needed a:
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)

Trying to persist to an oracle db using hibernate 4 and spring 3 without success. Tests pass but data not persisted.

I am trying to implement a simple DAO using hibernate 4 and Spring 3.
When I try to save or delete a row in the db the transaction is not persisted. I have included some code to show how the saving in the db doesnt work:
I have a junit test which simply tries to save a StockEntityDTO in the db.
#RunWith(SpringJUnit4ClassRunner.class)
public class StocksDAOImplTest extends
AbstractTransactionalJUnit4SpringContextTests {
#Autowired
protected StocksDAO stockDao;
#Test
public void shouldInsertIntoDatabase() {
BigDecimal price = new BigDecimal(653.50);
StockEntityDTO savedStock = new StockEntityDTO("GOOG", price, "google");
stockDao.create(savedStock);
StockEntityDTO retrievedStock = stockDao.getById(savedStock.getId());
assertEquals(savedStock, retrievedStock);
}
The test passes but the expected row (1, "GOOG", 653.50, "google") is not persisted in the db.
The DAO looks like this:
#Transactional
public abstract class AbstractHibernateDAO<T extends Serializable> {
private Class<T> clazz;
#Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
public void setClazz(final Class<T> clazzToSet) {
this.clazz = clazzToSet;
}
public void create(final T entity) {
Session session = this.getCurrentSession();
session.save(entity);
}
Application Context:
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:orcl" />
<property name="username" value="gtp" />
<property name="password" value="gtp" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.ubs.gtp.data.domain" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext
</prop>
</props>
</property>
</bean>
Hope someone can help. As is probably evident from my code, I am very new to spring.
AbstractTransactionalJUnit4SpringContextTests rolls back after the test. Try setting a breakpoint at the last line and then inspecting the database. You can use the Rollback annotation if you don't want this default behaviour.

Resources