Spring + Hibernate使用来自DB的值填充持有者类 [英] Spring + Hibernate populating holder class with values from DB

查看:99
本文介绍了Spring + Hibernate使用来自DB的值填充持有者类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的web应用程序,我将从静态数据库表中加载一些细节,我打算在容器在单例bean中的HolderClass上启动时加载这些细节。我会在需要使用静态数据的地方注入这个类。所以基本上我想避免每次从DB加载静态数据。



当前实现:

  public Class CountryHolder(){
List< Country>所有国家;

public void init(){
this.countries = loadAllCountries;
}

公共列表< Country> loadAllCountries(){
//使用JDBC模板执行数据库选择查询
}

上面的实现非常好,init方法加载了我的bean的国家列表。但是现在我已经迁移到Hibernate,Country是Persisten Entity。

Hibernate:

  @Transactional(readOnly =true) 
公共列表< Country> loadAllCountries(){
return countryDao.findAll();

请注意我跳过了注入dao和jdbc模板的代码。但问题是,因为我在init方法中调用此方法,Hibernate抱怨没有发现此会话,尽管我已将其声明为readOnly事务。



请告知

解决方案

好的,我会发布我的在服务器上下文加载时从DB加载主服务器。


$ b HibernateHelper.java

  public final class HibernateHelper 
{
private static SessionFactory sessionFactory;

static
{
try {
//从标准(hibernate.cfg.xml)
// config文件创建SessionFactory。

配置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);



$ b public Session getSession()
{
SessionFactory sessionFactory = getSessionFactory();
return sessionFactory.openSession();
}

private static SessionFactory getSessionFactory()
{
return sessionFactory;






HibernateHelper类将帮助 buildSessionFactory 通过阅读 hibernate.cfg.xml 。该类有 getSession(),它返回 session` 。



HibernateHelper_DI.xml

 < bean id =Hhelperclass =util.HibernateHelper/> 

负责创建HibernateHelper的singalton bean的DI xml文件。

MasterHelper.java $ b

  public最终的类MasterHelper实现ApplicationContextAware 
{
private static getMasterServiceImpl runtimeServiceImpl;
private static List< Master>主人= NULL;

public static List< Master> getMasters()
{
if(masters == null)
{
loadMasters();
}
回报大师;
}

private static void loadMasters()
{
try
{
if(masters == null){
主人= runtimeServiceImpl.getMasters();
}
}
catch(异常e)
{
masters = null;
throw e;


$ b @Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {

runtimeServiceImpl =(getMasterServiceImpl )applicationContext
.getBean(getMasterService);
}


}

getMasterService_DI.xml

 < bean id =getMasterServiceclass =service.getMasterServiceImpl/> 

负责创建getMasterServiceImpl的singalton bean的DI xml文件。

MasterHelper_DI.xml

 < ; bean id =MasterHelperclass =service.MasterHelper/> 

一个DI xml文件,负责创建MasterHelper的singalton bean。

通过此配置。 spring知道DI文件在哪里读取。

root-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。



当您调用 MasterHelper.getMasters(); 第一次在Web应用程序中的任何地方,它将去DB加载主人并分配给静态主人。下次您拨打 MasterHelper.getMasters( ); 它会检查是否为静态 master



如果你想要在创建bean的时候你需要加载主设备,那么你可以在MasterHelper中使用change method setApplicationContext(),如下所示:

  @Override 
public void setApplicationContext(ApplicationCont ext applicationContext)
抛出BeansException {

runtimeServiceImpl =(getMasterServiceImpl)applicationContext
.getBean(getMasterService);
loadMasters(); //只能在这里调用,BCOZ loadMasters需要BEAN OF getMasterServiceImpl
}

将会帮助你。

以上所有代码仅在此处手动编写,因此可能存在一些语法错误,如果发现任何错误, / strong>


For my web app I will loading a few details from the static DB tables which I plan to load when the container starts up on a HolderClass in a singleton bean. I will inject this class wherever I wish to use the static data. So basically I want to avoid loading the static data everytime from DB

Current Implementation:

public Class CountryHolder(){
    List<Country> allCountries;

    public void init(){
       this.countries = loadAllCountries;
    }

    public List<Country> loadAllCountries(){
     // Perform DB select query using JDBC template
    }

The above implementation works perfectly fine that is the init method loads the list of Countries for my bean. But now I have migrated to Hibernate and Country is a Persisten Entity.

Hibernate:

@Transactional(readOnly ="true")
public List<Country> loadAllCountries(){
   return countryDao.findAll();
}

Please note I have skipped the code where I am injecting the dao and jdbc template. But the issue is that since I am calling this method in init method Hibernate complains about no session found to this although I have declared it as a readOnly transaction.

Please advise

解决方案

Okay then I will just post what I did to load Masters from DB on server context loading.

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 class will help to buildSessionFactory by reading hibernate.cfg.xml.This class having getSession()which returnsession`.

HibernateHelper_DI.xml

<bean id="Hhelper" class="util.HibernateHelper" />

An DI xml file which is responsible for creating singalton bean of HibernateHelper.

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" />

An DI xml file which is responsible for creating singalton bean of getMasterServiceImpl.

MasterHelper_DI.xml

<bean id="MasterHelper" class="service.MasterHelper" />

An DI xml file which is responsible for creating singalton bean of MasterHelper.

By this config. spring knows from where DI files is get read.

root-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>

When context loading is going on, with the help of web.xml and root-context.xml spring reads DI files and make beans accordingly.

When HibernateHelper bean is created sessionfactory is also created and kept in static object.In the same fashion when MasterHelper bean is created.

When you call MasterHelper.getMasters(); for the first time anywhere in web application it will goes to DB load the masters and assign to static masters.Next time when you call MasterHelper.getMasters(); it will check for null condition to static master.

if you want at the time of bean creation you want to load masters then you can use change method setApplicationContext() in MasterHelper as follows:

    @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
     }   

Hope This will help you.

All above code is written manually at here only so there may be some syntax error(s) are there, please correct if any found

这篇关于Spring + Hibernate使用来自DB的值填充持有者类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆