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.
Related
This question already has answers here:
What exactly is Field Injection and how to avoid it?
(4 answers)
Spring setter injection and constructor injection
(2 answers)
Spring Auto Components Scanning with Constructor injection
(3 answers)
Closed 4 years ago.
I have library module which I want to use to store Hibernate models. I ask have Spring WAR package which I want to use.
Main Spring WAR:
#Configuration
#EnableTransactionManagement
public class ContextDatasource {
#Bean
public LocalSessionFactoryBean sessionFactory() throws NamingException {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "org.plugin.database.models" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() throws NamingException {
return (DataSource) new JndiTemplate().lookup("java:/global/production_gateway");
}
#Bean
public PlatformTransactionManager hibernateTransactionManager() throws NamingException {
final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private final Properties hibernateProperties() {
final Properties hibernateProperties = new Properties();
return hibernateProperties;
}
}
Library DAO:
public class BlacklistsDaoHibernate implements BlacklistsDao {
Session session;
#Autowired
SessionFactory sessionFactory;
public BlacklistsDaoHibernate() {
session = sessionFactory.getCurrentSession();
}
#Override
public void saveOrUpdate(BlacklistsModel blacklistsModel) throws Exception {
try {
session.getTransaction().begin();
session.saveOrUpdate(blacklistsModel);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
throw new Exception("Error");
}
}
But I get NPE at this line session = sessionFactory.getCurrentSession();
What is the proper way to use sessionFactory into the Library Jar module?
You can use #PostConstruct or constructor injection. Spring instantiates your object, then resolves its #Autowired fields. You can ask that it resolve your object's dependencies prior to instantiating the object via constructor injection.
With constructor injection:
SessionFactory sessionFactory;
Session session;
public BlacklistsDaoHibernate(#Autowired SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
this.session = sessionFactory.getCurrentSession();
}
With #PostConstruct:
#Autowired
SessionFactory sessionFactory;
Session session;
#PostConstruct
void init() {
this.session = sessionFactory.getCurrentSession();
}
Edit: If your goal is just to resolve the NullPointerException as mentioned in the comments, use this instead:
#PostConstruct
void init() {
this.session = sessionFactory.openSession();
}
There's an example of the typical usage of SessionFactory at https://www.java2novice.com/hibernate/session-factory.
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'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();
Problem:
entityManager.unwrap(SessionImplementor.class) cause no transactional entitymanager available exception.
Code:
#Component
public class HibernateEventWiring {
#Autowired
private ViewListener listener;
#PersistenceContext(unitName = "config-punit")
private EntityManager entityManager;
#PostConstruct
public void registerListeners() {
SessionFactory sessionFactory = getSessionFactory();
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(
EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener(listener);
}
#Transactional
private SessionFactory getSessionFactory() {
// EXCEPTION: No transactional entitymanager available
return entityManager.unwrap(SessionImplementor.class).getFactory();
}
}
According to this excelent answer:
In the #PostConstruct (as with the afterPropertiesSet from the InitializingBean interface) there is no way to ensure that all the post processing is already done, so (indeed) there can be no Transactions.
As I see, you do not need a transaction nor an entity manager bean, but rather an entity manager factory bean. I think you should simply autowire the EntityManagerFactory and then unwrap the Hibernate SessionFactory from it.
#Autowired
private EntityManagerFactory entityManagerFactory;
#PostConstruct
public void registerListeners() {
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
...
}
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();
}