对于我的网络应用程序,我将从静态数据库表中加载一些详细信息,我计划在容器启动时在单例bean中的HolderClass上加载。我会在任何希望使用静态数据的地方注入这个类。所以基本上我想避免每次从DB
加载静态数据当前实施:
public Class CountryHolder(){
List<Country> allCountries;
public void init(){
this.countries = loadAllCountries;
}
public List<Country> loadAllCountries(){
// Perform DB select query using JDBC template
}
上面的实现完全正常,init方法为我的bean加载了Country列表。但是现在我已经迁移到了Hibernate,而Country则是一个Persisten Entity。
休眠:
@Transactional(readOnly ="true")
public List<Country> loadAllCountries(){
return countryDao.findAll();
}
请注意我已经跳过了我注入dao和jdbc模板的代码。但问题是,因为我在init方法中调用此方法,所以Hibernate抱怨没有找到会话,尽管我已将其声明为readOnly事务。
请告知
答案 0 :(得分:0)
首先,由于Spring本身不执行持久性,因此无法指定readOnly应该具有什么意义。这个属性只是对提供者的一个提示,行为取决于,在这种情况下,Hibernate。
如果将readOnly指定为true,则当前Hibernate会话中的刷新模式将设置为FlushMode.NEVER
,阻止会话提交事务。
此外,将在JDBC Connection上调用setReadOnly(true)
,这也是底层数据库的提示。如果你的数据库支持它(很可能它),它与FlushMode.NEVER的效果基本相同,但它更强大,因为你甚至无法手动刷新。
如果您发布Hibernate context
<强>更新强>
您对使用ApplicationContext
或DI
我的想法是使用一个bean class
,它将在spring容器加载时加载。在bean class
中你将连接到DB fetch记录并使用你想要使用的地方而不去每次都要DB。
我在我的项目中执行此操作,我在服务器上下文加载时从DB获取一些菜单,并且每次都使用它而不使用roundTriping到DB。
答案 1 :(得分:0)
好的,那么我将发布我在服务器上下文加载时从DB加载Masters所做的工作。
<强> HibernateHelper.java 强>
public final class HibernateHelper
{
private static SessionFactory sessionFactory;
static
{
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
Configuration cfg = new Configuration();
cfg.configure("hibernate.cfg.xml");
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties)).buildServiceRegistry();
SessionFactory tempSessionFactory = cfg.buildSessionFactory(sr);
sessionFactory = tempSessionFactory;
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public Session getSession()
{
SessionFactory sessionFactory = getSessionFactory();
return sessionFactory.openSession();
}
private static SessionFactory getSessionFactory()
{
return sessionFactory;
}
}
HibernateHelper类可以通过阅读buildSessionFactory
来帮助hibernate.cfg.xml
。这个课程有getSession()which return
个会话。
<强> HibernateHelper_DI.xml 强>
<bean id="Hhelper" class="util.HibernateHelper" />
一个DI xml文件,负责创建HibernateHelper的singalton bean。
<强> MasterHelper.java 强>
public final class MasterHelper implements ApplicationContextAware
{
private static getMasterServiceImpl runtimeServiceImpl;
private static List<Master> masters=null;
public static List<Master> getMasters()
{
if(masters==null)
{
loadMasters();
}
return masters;
}
private static void loadMasters()
{
try
{
if(masters==null){
masters=runtimeServiceImpl.getMasters();
}
}
catch(Exception e)
{
masters=null;
throw e;
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
runtimeServiceImpl= (getMasterServiceImpl) applicationContext
.getBean("getMasterService");
}
}
<强> getMasterService_DI.xml 强>
<bean id="getMasterService" class="service.getMasterServiceImpl" />
一个DI xml文件,负责创建getMasterServiceImpl的singalton bean。
<强> MasterHelper_DI.xml 强>
<bean id="MasterHelper" class="service.MasterHelper" />
一个DI xml文件,负责创建MasterHelper的singalton bean。
通过此配置。 spring知道从哪里读取DI文件。
<强>根context.xml中强>
<import resource="classpath:DI/*.xml" />
<强>的web.xml 强>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
当进行上下文加载时,在web.xml
和root-context.xml
的帮助下,spring读取DI文件并相应地生成bean。
当创建HibernateHelper
bean时,还会创建sessionfactory
并将其保存在静态对象中。以同样的方式创建MasterHelper
bean时。
当您第一次在Web应用程序中的任何地方呼叫MasterHelper.getMasters();
时,它将转到数据库加载主服务器并分配给静态masters
。下次当您致电MasterHelper.getMasters();
时,它将检查for null condition to static master
。
如果您想在bean创建时想要加载母版,那么您可以在MasterHelper中使用更改方法setApplicationContext()
,如下所示:
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
runtimeServiceImpl= (getMasterServiceImpl) applicationContext
.getBean("getMasterService");
loadMasters(); //IMPOTANT TO CALL HERE ONLY,BCOZ loadMasters NEED BEAN OF getMasterServiceImpl
}
希望这会对你有帮助。
以上所有代码都是手动编写的,因此可能存在一些语法错误,如果找到则请更正