Creating Table Using Hibernate and Oracle - spring

I would like to create a simple table "account" using hibernate in an oracle database.
Here's my bean class Account:
#Entity
#Table(name = "account")
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(nullable = false)
private String id;
#Column(nullable = false)
private String iban;
#Column(nullable = false)
private String name;
#Column(name = "`usage`", nullable = false)
private String usage;
#Column(nullable = false)
private String type;
#Column(nullable = false)
private String ccy;
#Column(nullable = false)
private String psuStatus;
#Column(nullable = false)
private String balances;
public Account() {
}
public Account(String id, String iban, String name, String usage,
String type, String ccy, String psuStatus, String balances) {
this.id = id;
this.iban = iban;
this.name = name;
this.usage = usage;
this.type = type;
this.ccy = ccy;
this.psuStatus = psuStatus;
this.balances = balances;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getIban() {
return iban;
}
public void setIban(String iban) {
this.iban = iban;
}
public String getUsage() {
return usage;
}
public void setUsage(String usage) {
this.usage = usage;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCcy() {
return ccy;
}
public void setCcy(String ccy) {
this.ccy = ccy;
}
public String getPsuStatus() {
return psuStatus;
}
public void setPsuStatus(String psuStatus) {
this.psuStatus = psuStatus;
}
public String getBalances() {
return balances;
}
public void setBalances(String balances) {
this.balances = balances;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
And here's the config file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx" 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.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- dataSource (connexion vers la base de données) -->
<!-- dataSource côté serveur <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/myDataSource"
/> -->
<!-- datasource locale -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="removed for privacy purposes" />
<property name="username" value="removed for privacy purposes" />
<property name="password" value="removed for privacy purposes" />
</bean>
<!-- support d'annotations JPA -->
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- config de la sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>fr.bnpparibas.dsp2aisp.beans</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQL5InnoDBDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<!-- <prop key="hibernate.generate_statistics">true</prop> -->
<prop key="hibernate.hbm2ddl.auto">create</prop> <!-- update -->
<!-- Cache de niv2 -->
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<!-- Configuring Connection Pool -->
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">50</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.idle_test_period">2000</prop>
</props>
</property>
</bean>
<!-- support des transactions par annotations #Transactional -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="autodetectDataSource" value="true" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- MailService -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<!-- SMTP settings -->
<property name="host" value="smtp.dsl.ovh.net" />
<!-- <property name="port" value="21" /> -->
<!-- <property name="username" value="USER_NAME" />
<property name="password" value="PASSWORD" /> -->
<property name="javaMailProperties">
<!-- additional properties specific to JavaMail -->
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">false</prop>
<prop key="mail.smtp.starttls.enable">false</prop>
</props>
</property>
</bean>
<!-- surcouche de l'entityManager => Hibernate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="accountDao" class="fr.bnpparibas.dsp2aisp.daos.AccountDao">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>
</beans>
The problem is, when I run the app, it doesn't create the table account in the database. I used the same example with an MySQL JDBC driver and a wampserver and it worked perfectly. But with an Oracle driver, for some reason, it doesn't work. Anybody knows why?
UPDATE: I was able to display the error by setting the hbm2ddl logger to true, and here's what I have now:
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:673)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:711)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:385)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:30)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:558)
at java.sql.DriverManager.getConnection(DriverManager.java:675)
at java.sql.DriverManager.getConnection(DriverManager.java:219)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:153)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:144)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:196)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:159)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.tool.hbm2ddl.SuppliedConnectionProviderConnectionHelper.prepare(SuppliedConnectionProviderConnectionHelper.java:33)
at org.hibernate.tool.hbm2ddl.DatabaseExporter.<init>(DatabaseExporter.java:35)
at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:425)
at org.hibernate.tool.hbm2ddl.SchemaExport.create(SchemaExport.java:361)
at org.hibernate.tool.hbm2ddl.SchemaExport.create(SchemaExport.java:350)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:469)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:711)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:727)
at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:511)
at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:495)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1688)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1626)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at com.ibm.ws.webcontainer.webapp.WebApp.notifyServletContextCreated(WebApp.java:2384)
at com.ibm.ws.webcontainer31.osgi.webapp.WebApp31.notifyServletContextCreated(WebApp31.java:514)
at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1012)
at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6574)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:467)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApplication(DynamicVirtualHost.java:462)
at com.ibm.ws.webcontainer.osgi.WebContainer.startWebApplication(WebContainer.java:1132)
at com.ibm.ws.webcontainer.osgi.WebContainer.access$000(WebContainer.java:108)
at com.ibm.ws.webcontainer.osgi.WebContainer$3.run(WebContainer.java:944)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:522)
at java.util.concurrent.FutureTask.run(FutureTask.java:277)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1153)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.lang.Thread.run(Thread.java:785)
Does this mean that I need to define the oracle schema?
UPDATE 2: Now I have this error:
14:29:58.026 [Default Executor-thread-12] ERROR org.hibernate.tool.hbm2ddl.SchemaExport - HHH000389: Unsuccessful: create table account (id varchar(255) not null, balances varchar(255) not null, ccy varchar(255) not null, iban varchar(255) not null, name varchar(255) not null, psuStatus varchar(255) not null, type varchar(255) not null, `usage` varchar(255) not null, primary key (id)) ENGINE=InnoDB
14:29:58.027 [Default Executor-thread-12] ERROR org.hibernate.tool.hbm2ddl.SchemaExport - ORA-00911: invalid character
But what's strange is that I'm generating the query using Hibernate. I didn't write the query myself.

Related

Table not auto create in HeidiSql(mysql) by spring hibernate. And no error shows in console but jdbc details missing, my code details given below

Table not auto create in HeidiSql(mysql) by spring hibernate. And no error shows in console but jdbc details missing, my code details given below
Model class
my entity java class
#Entity
#Table(name = "Payment_Table")
public class Payment implements Serializable {
private static final long serialVersionUID = 4501753715497967062L;
#Id
#GeneratedValue
private int id;
private String transactionId;
private String vendor;
private Date paymentDate;
private double amount;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public Date getPaymentDate() {
return paymentDate;
}
public void setPaymentDate(Date paymentDate) {
this.paymentDate = paymentDate;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public Payment() {
super();
// TODO Auto-generated constructor stub
}
public Payment(String transactionId, String vendor, Date paymentDate, double amount) {
super();
this.transactionId = transactionId;
this.vendor = vendor;
this.paymentDate = paymentDate;
this.amount = amount;
}
}
application-context.xml
my data base configuration
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.spring.rest.curd.model.Payment</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernet.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-context.xml</param-value>
</context-param>
<display-name>Spring Rest Application</display-name>
<servlet>
<servlet-name>springRest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springRest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
springRest-servlet.xml
<context:component-scan base-package="com.spring.rest.curd.*"></context:component-scan>
<mvc:annotation-driven />
<tx:annotation-driven />

Exception Illegal Argument - unknown entity JPA - Additional package to scan for entities in application-context.xml is not taken into consideration

I am working on a Spring application which has a persistence unit configured in the application-context.xml. I need to add an additional package in in order to use new entities.
Even though this part of the persistence.xml file looks like below, my entities from the additional package are not seen by the application and I get an exception saying that the entity is unknown.
<bean id="transactionManager_students" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryStudents" />
<qualifier value="clientTransaction" />
</bean>
<bean id="entityManagerFactoryStudents"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="datasource_College" />
<property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
<property name="packagesToScan">
<list>
<value>com.load.model</value>
<value>com.students.entity</value>
</list>
</property>
<property name="persistenceUnitName" value="unit_stud" />
<property name="jpaProperties">
<props>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.hbm2ddl.auto">none</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>  
I also have to mention that I annotated the entities with #Entity and in the class where I am operating on the entities I have this ( the row with em.persist(student) is giving me the error )
#PersistenceContext(unitName = "unit_stud")
public EntityManager em;
public Student student;
#Transactional(value = "clientTransaction", propagation = Propagation.REQUIRED)
public long persistStudentObject() {
long studentId = 0;
try
{
logger.debug("Start Persisting...");
em.persist(student);
// unique ID
studentId = student.getId();
logger.debug("Persisting OK...");
}
catch (PersistenceException persistenceException)
{
logger.error("PersistenceException occur", persistenceException);
}
}
return studentId ;
}
The entity:
package com.students.entity;
#Entity
#Table(name = "STUDENTS", schema = "DEMO", catalog = "")
public class Student{
private long id;
private String firstname;
private String name;
private String streetnumber;
private String zipcodecity;
Can anyone help me? I do not know what to do in order to make my entities visible.

my code is executed successfully but data not stored in database with spring and hibernate

when i am going to execute this program.
my program is successfully executed but it doesn't store data in database.
what is the problem in this program.
this is my Employee.java class
package com.spring.demo;
public class Employee {
private int id;
private String name;
private float salary;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
}
this is my EmployeeDao.java class
package com.spring.demo;
import org.springframework.orm.hibernate5.HibernateTemplate;
public class EmployeeDao {
HibernateTemplate template;
public void setTemplate(HibernateTemplate template) {
this.template = template;
}
public void saveEmployee(Employee e) {
Integer i = (Integer) template.save(e);
if (i > 0) {
System.out.println("Success");
} else {
System.out.println("Not Success");
}
}
public void updateEmployee(Employee e) {
template.update(e);
}
public void deleteEmployee(Employee e) {
template.delete(e);
}
}
this is my Test.java class
package com.spring.demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext bean = new
ClassPathXmlApplicationContext("spring.xml");
EmployeeDao emp = (EmployeeDao) bean.getBean("obj");
Employee e = new Employee();
e.setId(2);
e.setName("Amit Goyal");
e.setSalary(40000);
emp.saveEmployee(e);
// emp.updateEmployee(e);
bean.close();
}
}
this is my Employee.hbm.xml file
<?xml version='1.0' encoding='UTF-8'?>
<!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.spring.demo.Employee" table="amit1234">
<id name="id">
<generator class="assigned"></generator>
</id>
<property name="name"></property>
<property name="salary"></property>
</class>
</hibernate-mapping>
and last this is my spring.xml file
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-
4.2.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="system" />
<property name="password" value="tiger" />
</bean>
<bean id="mysessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mappingResources">
<list>
<value>Employee.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect
</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="template"
class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="mysessionFactory"></property>
<property name="checkWriteOperations" value="false"></property>
</bean>
<bean id="obj" class="com.spring.demo.EmployeeDao">
<property name="template" ref="template"></property>
</bean>
</beans>
In this configuration you are missing transaction management configuration. Use #transactional annotation over your service method.
In you situation data is not committing in the database it just save the data and not commit the data in database.

Transaction support for Discriminator model in Muiti-tenancy with Spring + Hibernate

Our current development based on Discriminator model in Multi-tenancy. Following is the technical stack we are currently engage with,
Spring 3.1.1.RELEASE
Hibernate 4.1.6.Final
We are maintain tenant id by keep one column separately in each table. Tenant id filter when session is created.
Example model class.
#Entity
#FilterDef(name = "tenantFilter", parameters = #ParamDef(name = "tenantIdParam", type = "string"))
#Filters(#Filter(name = "tenantFilter", condition = "tenant_id = :tenantIdParam"))
#Table(name = "assessment")
public class Assessment implements java.io.Serializable, Comparable<Assessment> {
private static final long serialVersionUID = -2231966582754667029L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Long id;
#Column(name = "tenant_id", nullable = false, updatable = false)
private String tenantId;
// rest of the code...
}
This is the configuration of session factory
<!-- create database connection pool -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="jdbc:mysql://${jdbc.host}:3306/${jdbc.database}?createDatabaseIfNotExist=true&autoReconnect=true&useUnicode=true&connectionCollation=utf8_general_ci&characterEncoding=UTF-8" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="idleConnectionTestPeriodInMinutes" value="60"/>
<property name="idleMaxAgeInMinutes" value="240"/>
<property name="maxConnectionsPerPartition" value="30"/>
<property name="minConnectionsPerPartition" value="10"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="5"/>
<property name="statementsCacheSize" value="100"/>
<property name="releaseHelperThreads" value="3"/>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="lk.gov.elg.orm.model"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=${hibernate.dialect}
hibernate.hbm2ddl.auto=update
</value>
</property>
</bean>
<bean id="tenantBasedSessionFactory" class="lk.gov.elg.orm.dao.impl.TenantBasedSessionFactoryImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
Tenant base session factory
public class TenantBasedSessionFactoryImpl implements TenantBasedSessionFactory {
private SessionFactory sessionFactory;
#Override
public Session getTenantBasedSession(Object tenantId) {
Session session = sessionFactory.openSession();
session.enableFilter("tenantFilter").setParameter("tenantIdParam", tenantId);
return session;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getAllTenantBasedSession() {
Session session = sessionFactory.openSession();
return session;
}
}
sample Service class
#Service("assessmentService")
public class AssessmentServiceImpl implements AssessmentService {
#Autowired
private AssessmentDao assessmentDao;
public Long saveAssessment(Assessment assessment, Object tenantId) {
return assessmentDao.saveAssessment(assessment, tenantId);
}
}
Sample DAO class
#Repository("assessmentDao")
public class AssessmentDaoImpl implements AssessmentDao {
#Autowired
private TenantBasedSessionFactory tenantBasedSessionFactory;
public Long saveAssessment(Assessment assessment, Object tenantId) {
Session session = tenantBasedSessionFactory.getTenantBasedSession(tenantId);
try {
session.beginTransaction();
session.save(assessment);
session.getTransaction().commit();
return assessment.getId();
} catch (HibernateException e) {
logger.error("Error in persist assessment:", e);
session.getTransaction().rollback();
return null;
} finally {
session.close();
}
}
}
I would like to know is there a way to get the spring transaction support with this Discriminator model for database transactions ?
And the other thing is I would like to know is there any advantage of give transaction handling to spring rather than handling it by our side?
Thanks in advance.
i had similar problem and i have resolved it using aspect instead of customizing sessionfactory, so i can leverage annotation driven transaction support
Below code is for aspect which works on annotation #Tennant
#Aspect
public class TennantAspect {
#Autowired
private SessionFactory sessionFactory;
#Around("#annotation(Tennant)")
public Object enableClientFilter(ProceedingJoinPoint pjp) throws Throwable {
Object obj;
boolean isDAO=(pjp.getTarget() instanceof BaseDAO<?,?>);
try {
if(isDAO){
Authentication auth=SecurityContextHolder.getContext().getAuthentication();
if(auth!=null){
User user=(User) auth.getPrincipal();
this.sessionFactory.getCurrentSession().enableFilter("clientFilter").setParameter("clientId", user.getClientId());
}
}
obj=pjp.proceed();
}finally {
if(isDAO)
this.sessionFactory.getCurrentSession().disableFilter("clientFilter");
}
return obj;
}
}
Hope this solves your problem.
Alternatively you can also look at tenancy support by hiberante & spring
http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch16.html
https://github.com/mariofts/spring-multitenancy

Why is Spring #Transactional returning old data and how can I get it to return up-to-date data?

I'm using Spring 3.1.0.RELEASE with Hibernate 4.0.1.Final. I'm trying to use the Spring transaction manager but am having an issue where Spring is returning old data for a find method. In my Spring application, I call a save method, and then a find method. After I call save, I can see the changes in the database, but when I call the find, it is returning the old state of the object. Here is the controller methods ...
// method to save
#RequestMapping(method = RequestMethod.POST)
public String saveUserEventFeeds(final HttpServletRequest request,
#ModelAttribute("eventFeeds") final Set<EventFeed> eventFeeds) {
final String nextPage = "user/eventfeeds";
try {
final String[] eventFeedIds = request.getParameterValues("userEventFeeds");
final Set<EventFeed> userEventFeeds = new HashSet<EventFeed>();
if (eventFeedIds != null) {
for (final String eventFeedId : eventFeedIds) {
final EventFeed eventFeed = getEventFeed(eventFeeds, Integer.parseInt(eventFeedId));
userEventFeeds.add(eventFeed);
} // for
} // if
final Registration currentUser = (Registration) securityContextFacade.getContext().getAuthentication().getPrincipal();
userService.saveUserEventFeeds(currentUser.getId(), userEventFeeds);
} catch (Exception exc) {
LOG.error(exc.getMessage(), exc);
} // try
return nextPage;
} // saveUserEventFeeds
// method to retrieve user
#ModelAttribute("user")
public UserDetails getUser() {
final Registration reg = (Registration) securityContextFacade.getContext().getAuthentication().getPrincipal();
final int id = reg.getId();
final Registration foundUser = userService.findUserById(id);
return (UserDetails) foundUser;
} // getUser
and here is the service where i declare everything transactional ...
#Transactional(rollbackFor = Exception.class)
#Component("userService")
public class UserServiceImpl implements UserService {
...
#Override
public void saveUserEventFeeds(Integer userId, Set<EventFeed> eventFeeds) {
final Registration searchUser = new Registration();
searchUser.setId(userId);
final Registration user = usersDao.getUser(searchUser);
if (user != null) {
user.setUserEventFeeds(eventFeeds);
usersDao.saveUser(user);
} else {
throw new RuntimeException("User with id " + userId + " not found.");
} // if
}
#Override
public Registration findUserById(Integer id) {
final Registration searchUser = new Registration();
if (id != null) {
searchUser.setId(id);
} // if
return usersDao.getUser(searchUser);
}
Below is the transaction manager I've declared in my application context file. If you can see how I can configure things differently so that I can get the most current data on my finds, please let me know.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/myproj"/>
<property name="username" value="myproj"/>
<property name="password" value="password"/>
<property name="maxActive" value="10"/>
<property name="minIdle" value="5"/>
<!-- SELECT 1 is a simple query that returns 1 row in MySQL -->
<property name="validationQuery" value="SELECT 1"/>
</bean>
<bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" id="sessionFactory">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.myco.myproj.domain.Registration</value>
<value>com.myco.myproj.domain.Role</value>
<value>com.myco.myproj.domain.EventFeed</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="show_sql">true</prop>
<prop key="dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<tx:annotation-driven />

Resources