I need to use hibernate with 2 or more bases. Since these bases have the same table, I imagine that there will be no problem when using the same objects paras tables that repeat. So being, I wonder how to spend other files on HibernateUtil establishing the connection, using different files hibernate.cfg.xml, but with the same mapping properties.
I imagine it's something along these lines:
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
but i dont have idea how to configure a other file.
The thing is to have 2 different session factory providers, each one configured with its corresponding data base.
In the example below HibernateUtilDb1 will use the configuration in hibernate-db1.cfg.xml, and HibernateUtilDb2 will use hibernate-db2.cfg.xml.
public class HibernateUtilDb1 {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
return new Configuration().configure("hibernate-db1.cfg.xml").buildSessionFactory();
}
catch (Throwable ex) { ...}
}
...
And:
public class HibernateUtilDb2 {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
return new Configuration().configure("hibernate-db2.cfg.xml").buildSessionFactory();
}
catch (Throwable ex) { ...}
}
...
Related
I have two classes out of which I want to use only one class at run-time (depending on if I am running tests or executing the app on a server(local or otherwise)) and exclude the other from Spring's Component Scanning.
Here the 1st class which I want to use when testing:
public class HibernateUtilForH2 implements HibernateUtil {
private static SessionFactory sessionFactory;
static {
try {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml.h2");
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}
public Session openSession() {
return sessionFactory.openSession();
}
}
Here's the second class for usage during production or local execution:
public class HibernateUtilForMySql implements HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}
HibernateUtil here is an interface containing declaration of openSession() method only.
I want HibernateUtilForH2 to be injected using DI when testing and HibernateUtilForMySql to be used for production or execution on a local server. How do I do that?
I've tried using #TestComponent and #ConditionalOnWebApplication but neither seems to work. I need a solution that is compatible with GitLab's CI/CD setup so that deployments can be smooth and hassle-free.
You could work with profiles.
Annotate your integration test with #ActiveProfiles("test") and your component that should be loaded for integration tests with #Profile("test") and the Components that should not be loaded for integration tests with #Profile("!test")
I have JSF maven project with Hibernate. There are some DAO classes in project, but it have failed implementation I think.
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().
applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
In each DAO I call this method
Session mySession = HibernateUtil.getSessionFactory().openSession();
And After that doing transactions.
Now I want create generic BaseDAO class and create base CRUD operations in it. But I need get EntityManager. How can I getEntityManager in my BaseDao?
In spring I do it:
public class BaseJpaDao<E> implements BaseDao<E>{
protected Class<?> entityClass;
#PersistenceContext(unitName = "mainDataBase")
private EntityManager entityManager;
public BaseJpaDao(Class<?> entityClass) {
this.entityClass = entityClass;
}
#Override
public E persist(E e) {
entityManager.persist(e);
return e;
}
But how do it in not spring project?
Use Hibernates factory methods:
// Use persistence.xml configuration
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mainDataBase")
EntityManager em = emf.createEntityManager();
// Retrieve an application managed entity manager
// Work with the EM
em.close();
Taken from the docs.
I'm using hibernate annotation in my program, but its getting error.
It returns no session factory that I opened. I used netbeans IDE and when I debug my program, it want to open a session and next step, it is going to InvocationTargetException.java and do not anything else.
it is my folders
enter image description here
it is my hibernate util
public class HibernatUtil {
private static final SessionFactory FACTORY;
static {
FACTORY = new AnnotationConfiguration().configure("/hibernate.cfg.xml").buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return FACTORY;
}
}
it is my class that get session factory, but getting error
public class UserDAO {
private Session session;
public boolean insert(User user){
session=HibernatUtil.getSessionFactory().getCurrentSession();
Transaction transaction=null;
String result;
try{
transaction=session.beginTransaction();
session.save(user);
transaction.commit();
result="your insert was sucssedfull";
}
catch(Exception e ){
result="your transaction was faild";
if (transaction!=null) transaction.rollback();
}
System.out.println(result);
return transaction!=null ;
}
}
and then after next step go too this class
enter image description here
Try using this HibernateUtil instead :
public class HibernateUtil {
public static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
and in your userDao use this :
private final SessionFactory sessionFactory = HibernateUtil.sessionFactory.getCurrentSession();
In the hibernate documentation for version 4.3.0.Final the following code snippet is given to create a SessionFactory:
package org.hibernate.tutorial.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
This seems to be outdated, as the method buildSessionFactory() is deprecated. What is the correct way to create the SessionFactory?
public class TestHB4 {
private static StandardServiceRegistry serviceRegistry;
private static SessionFactory sessionFactory;
public static void main(String[] args) {
Person person = new Person();
person.setFirstName("Namal");
person.setLastName("Dinesh");
Configuration configuration = new Configuration().configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.configure().buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
session.close();
}
A week before we migrated the application from hibernate3 to hibernate4 every thing worked fine in hibernate3 but after migrating to hibernate4. I keep getting nested transactions not supported.
Below is my service layer which is calling the dao
public class LeaveApplicationService implementsSerializable,LeaveApplicationInterfaceService{
#Autowired
private LeaveApplicationInterfaceDao _leavApplicationInterfaceDao;
//getter setter
#Override
public synchronized void clickOnAddLeaveButton(LeaveApplicationViewBean leaveApplicationViewBean) {
SessionFactory sessionFactory=(SessionFactory) ObjectFactory.getBean("sessionFactory");
sessionFactory.getCurrentSession().beginTransaction();
try{
leaveApplicationViewBean.get_employeeListObj().clear();
leaveApplicationViewBean.get_leaveTypelist().clear();
leaveApplicationViewBean.get_leaveApproveers().clear();
//leaveApplicationViewBean.set_employeeListObj(get_leavApplicationInterfaceDao().getEmployeeList());
leaveApplicationViewBean.set_leaveTypelist(get_leavApplicationInterfaceDao().getLeaveType());
leaveApplicationViewBean.set_leaveApproveers(get_leavApplicationInterfaceDao().getLeaveApprover(CmsUtil.getSession("userId").toString()));
}catch(Exception e){
CmsLogger.errorLog(LeaveApplicationService.class, e);
}finally{
sessionFactory.getCurrentSession().close();
}
}
The Dao layer
public class LeaveApplicationDao extends TransactionService implements Serializable,LeaveApplicationInterfaceDao{
private static final long serialVersionUID = 6237725881698448330L;
public List<LeaveApprover> getLeaveApprover(String userId) throws Exception {
List<LeaveApprover> _leavApprovers=new ArrayList<LeaveApprover>();
Iterator it=getSessionFactory().getCurrentSession().createQuery(sql.toString()).setParameter("practiceAreaId",CmsUtil.getSession("practiceAreaId").toString()) .setParameter("userId",userId).setCacheable(true)
.list().iterator();
while(it.hasNext()){
Object[] obj=(Object[]) it.next();
LeaveApprover leaveApprover=new LeaveApprover();
leaveApprover.set_approverId((String) obj[0]);
leaveApprover.set_approverName((String) obj[1]);
_leavApprovers.add(leaveApprover);
}
return _leavApprovers;
}
public List<TimeProjectCategory> getLeaveType() throws Exception{
List<TimeProjectCategory> timeProjectCategories=new ArrayList<TimeProjectCategory>();
Iterator it =getSessionFactory().getCurrentSession().createQuery(sql.toString()).setCacheable(true).list().iterator();
while(it.hasNext()){
Object[] obj=(Object[]) it.next();
TimeProjectCategory category=(TimeProjectCategory) ObjectFactory.getBean("domainTimeProjectCategoryObj");
category.getProjectId().set_projectId((String) obj[0]);
category.setTimeCategory((String) obj[1]);
category.setTimeProjectCategoryId((String) obj[2]);
timeProjectCategories.add(category);
}
return timeProjectCategories;
}
}
And my TransactionService class
public class TransactionService{
/**
*
*/
private static final long serialVersionUID = 3747504246445270484L;
#Autowired
private DataSource dataSource;
#Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
And the exception I see in the stack-track is
Stack Trace for the code
My db.xml
db.xml file
There are two possibilities:
Implementation-defined behavior with open transactions on session close:
Make sure you commit (or rollback, doesn't matter for read-only) the transaction before closing the connection. Hibernate Session.close() closes the underlying connection; and http://docs.oracle.com/javase/6/docs/api/java/sql/Connection.html#close%28%29 states that the behavior when a transaction is open is implementation-defined (i.e. some implementations will automatically close the transaction, others may reference count the connection and hold it open).
The general pattern is:
try {
Transaction t = sessionFactory.getCurrentSession().beginTransaction();
try {
// do work
t.commit();
} catch (Exception e) {
t.rollback();
throw e;
}
} finally {
sessionFactory.getCurrentSession().close();
}
A previous transaction is still active:
If a previous transaction is still active from somewhere else, you can do this:
Transaction t = session.getTransaction();
if (t == null || !t.isActive())
t = session.beginTransaction();
// then use t (or session's current transaction, same thing)
Or, if you're not passing the Transaction around:
if (session.getTransaction() == null || !session.getTransaction().isActive())
session.beginTransaction();
// then use session's current transaction
But you will still probably want to examine your code to see where else a transaction is being opened on a given connection.