Hibernate 4 在抽象工厂中创建sessionfactory
Hibernate 4 create sessionfactory in Abstract Factory
我在使用 Hibernate 4.2 的网络应用程序中工作,我实现了抽象工厂模式,但是为了创建会话工厂,我没有 init 方法,因为我使用第一个调用来创建会话工厂以在像静态一样向前,就像你可以看到我从 DAOImpl 获得会话,开始工作,最后我关闭它。首先我想问一下这个做法对不对?还有其他更好的做法吗?
public class HibernateSessionFactory {
private static SessionFactory sessionFactory = buildSessionFactory();
private static final Logger logger = LogManager.getLogger(HibernateSessionFactory.class);
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactory sf = configuration.buildSessionFactory(sr);
return sf;
} catch (Exception ex) {
logger.error("Initial SessionFactory creation failed.", ex);
ex.printStackTrace();
throw ex;
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdownSessionFactory() {
sessionFactory.close();
}
}
DAOIMPL
public class RecordDAOImpl implements RecordDAO{.....
public String getRecord (Long id){
Session session = HibernateSessionFactory.getSessionFactory().openSession();
try {
session.beginTransaction();
.
.
.
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
} finally {
session.close();
}
return value;
}
DAO
public interface FieldDAO {.....
String getRecord (Long id);
工厂
public class HibernateFactoryDao extends DAOFactory {...
@Override
public RecordDAOImpl getRecordDAO() {
return new RecordDAOImpl();
}
作为替代方案,您可以使用 CDI 将您的工厂注入 RecordDAOImpl
并根据您的 ORM 类型检索您的会话。
作为一个可能的例子,您可以尝试以下操作:
1. 创建限定符以在 ORM 工厂之间针刺
@Qualifier
@Retention(RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER })
public @interface ORMSessionFactory {
ORMType value();
public enum ORMType {
HIBERNATE,
ECLIPSELINK;
}
}
2. 为会话工厂定义接口
public interface MySessionFactory {
public SessionFactory getSessionFactory();
public void shutdownSessionFactory();
}
3. 如有必要,创建一个抽象 class 来保存所有 ORM 工厂实现中的通用行为
public abstract class AbstractSessionFactory implements MySessionFactory {
protected SessionFactory sessionFactory;
public AbstractSessionFactory() {
buildSessionFactory();
}
@Override
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Override
public void shutdownSessionFactory() {
if (sessionFactory != null) {
sessionFactory.close();
}
}
protected abstract SessionFactory buildSessionFactory();
}
4. 用相应的类型注释您的 ORM 工厂实现
@ORMSessionFactory(ORMType.HIBERNATE)
public class HibernateSessionFactory extends AbstractSessionFactory {
@Override
protected SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
ServiceRegistry sr = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(sr);
return sessionFactory;
} catch (Exception ex) {
throw ex;
}
}
}
5. 然后,在您的 RecordDAOImpl
上,您可以执行以下操作
public class RecordDAOImpl implements RecordDAO {
@Inject
@ORMSessionFactory(ORMType.HIBERNATE)
private MySessionFactory mySessionFactory;
@Override
public String getRecord(Long id) {
String value = null;
Session session = mySessionFactory.getSessionFactory().openSession();
try {
session.beginTransaction();
// do some transactional stuff
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
} finally {
session.close();
}
return value;
}
}
不要忘记,为了启用 CDI,您的 META-INF[=47= 中应该有一个 beans.xml ] (JAR) 或 WEB-INF 文件夹 (WAR):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
我在使用 Hibernate 4.2 的网络应用程序中工作,我实现了抽象工厂模式,但是为了创建会话工厂,我没有 init 方法,因为我使用第一个调用来创建会话工厂以在像静态一样向前,就像你可以看到我从 DAOImpl 获得会话,开始工作,最后我关闭它。首先我想问一下这个做法对不对?还有其他更好的做法吗?
public class HibernateSessionFactory {
private static SessionFactory sessionFactory = buildSessionFactory();
private static final Logger logger = LogManager.getLogger(HibernateSessionFactory.class);
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactory sf = configuration.buildSessionFactory(sr);
return sf;
} catch (Exception ex) {
logger.error("Initial SessionFactory creation failed.", ex);
ex.printStackTrace();
throw ex;
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdownSessionFactory() {
sessionFactory.close();
}
}
DAOIMPL
public class RecordDAOImpl implements RecordDAO{.....
public String getRecord (Long id){
Session session = HibernateSessionFactory.getSessionFactory().openSession();
try {
session.beginTransaction();
.
.
.
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
} finally {
session.close();
}
return value;
}
DAO
public interface FieldDAO {.....
String getRecord (Long id);
工厂
public class HibernateFactoryDao extends DAOFactory {...
@Override
public RecordDAOImpl getRecordDAO() {
return new RecordDAOImpl();
}
作为替代方案,您可以使用 CDI 将您的工厂注入 RecordDAOImpl
并根据您的 ORM 类型检索您的会话。
作为一个可能的例子,您可以尝试以下操作:
1. 创建限定符以在 ORM 工厂之间针刺
@Qualifier
@Retention(RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER })
public @interface ORMSessionFactory {
ORMType value();
public enum ORMType {
HIBERNATE,
ECLIPSELINK;
}
}
2. 为会话工厂定义接口
public interface MySessionFactory {
public SessionFactory getSessionFactory();
public void shutdownSessionFactory();
}
3. 如有必要,创建一个抽象 class 来保存所有 ORM 工厂实现中的通用行为
public abstract class AbstractSessionFactory implements MySessionFactory {
protected SessionFactory sessionFactory;
public AbstractSessionFactory() {
buildSessionFactory();
}
@Override
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Override
public void shutdownSessionFactory() {
if (sessionFactory != null) {
sessionFactory.close();
}
}
protected abstract SessionFactory buildSessionFactory();
}
4. 用相应的类型注释您的 ORM 工厂实现
@ORMSessionFactory(ORMType.HIBERNATE)
public class HibernateSessionFactory extends AbstractSessionFactory {
@Override
protected SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
ServiceRegistry sr = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(sr);
return sessionFactory;
} catch (Exception ex) {
throw ex;
}
}
}
5. 然后,在您的 RecordDAOImpl
上,您可以执行以下操作
public class RecordDAOImpl implements RecordDAO {
@Inject
@ORMSessionFactory(ORMType.HIBERNATE)
private MySessionFactory mySessionFactory;
@Override
public String getRecord(Long id) {
String value = null;
Session session = mySessionFactory.getSessionFactory().openSession();
try {
session.beginTransaction();
// do some transactional stuff
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
} finally {
session.close();
}
return value;
}
}
不要忘记,为了启用 CDI,您的 META-INF[=47= 中应该有一个 beans.xml ] (JAR) 或 WEB-INF 文件夹 (WAR):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>