简体   繁体   中英

Queries bean is null, how do I get it to populate?

so I'm trying to run a sql query within this java app. I think I have the DAO set up correctly but it can't find the XML file which contains my queries. The code in question for my DAO implementation is:

private Properties queries;

public void setQueries(Properties queries) {
    this.queries = queries;
}
public Boolean checkAssigned(String Id) {
    String sql = queries.getProperty("CHECK_IF_ASSIGNED");

    Map<String,Object> params = new HashMap<>();
    List<String> assignedList;
    params.put(":Id",Id);

    LOG.info("Checking to see if already assigned \n" + "sql=" + sql
            + "\n" + "params=" + params);

    assignedList = getNamedParameterJdbcTemplate().query(sql,params,
            new assignedMapper());
    if (assignedList == null || assignedList.size() == 0) {
        ScreenVo.setSwitch(false);
    }
    else {
        ScreenVo.setSwitch(true);
    }
    return ScreenVo.getSwitch();
}

My DAO is just:

public interface ScreenDao {
    Boolean checkAssigned(String Id);
}

My queries.xml file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/util
                           http://www.springframework.org/schema/util/spring-util.xsd">

    <util:properties id="queries">
        <prop key="CHECK_IF_ASSIGNED">
            <![CDATA[
                --Long query
            ]]>
        </prop>
    </util:properties>
</beans>

The bean for the dao in the applicationContext.xml is:

<bean id="screenDaoImpl" class="com.corp.apps.actionator.dao.ScreenDaoImpl">
    <property name="dataSource" ref="datasource"/>
    <property name="queries" ref="queries"/>
</bean>

And my declaration of the queries file in the applicationContext is:

<import resource="classpath:queries.xml"/>

It's declared in my web.xml in a similar fashion.

I tried to include everything that could possibly be relevant. I've tried autowiring the bean in ScreenDaoImpl.java but that didn't work. I'm really not sure where to go from here, or what I might have done wrong.

EDIT: The exception I'm getting is:

javax.faces.event.MethodExpressionActionListener.processAction java.lang.NullPointerException

And my screenDaoImpl is declared before use as:

private static ScreenDao screenDao = new ScreenDaoImpl();

Spring-Bean screenDaoImpl must be created through Spring context, in this case Spring can inject required properties ( dataSource and queries ) in created bean. I don't know your architecture of application. But I can offer you a couple of ways.

1 - If you want use screenDaoImpl in spring-bean which declared in spring-xml then you can do it like this:

<bean id="screenServiceImpl" class="com.corp.apps.actionator.service.ScreenServiceImpl">
    <property name="screenDao" ref="screenDaoImpl"/>
</bean>

The better way is make all your application in Spring. And create (and inject) beans by spring-context xml. Do not create bean-objects by new . Spring can not inject properties in these objects.

If it is difficult then try to find examples of applications on the Spring site. Maybe try spring-boot (without xml).

2 - If you want use screenDaoImpl in non-spring object you can get screenDaoImpl from spring-context by "bridge". Create class:

package com.corp.apps.actionator.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class AppSpringBridge implements ApplicationContextAware {

  private static ApplicationContext context;

  public void setApplicationContext(ApplicationContext context) throws BeansException {
    this.context = context;
  }

  public static ApplicationContext getApplicationContext() {
    return context;
  }
}

Define bean in application-context.xml:

<bean id="springBridge" class="com.corp.apps.actionator.util.AppSpringBridge />

Spring create this bean, but method getApplicationContext() (and context property) of this bean is static. And we can use getApplicationContext() in any methods:

ScreenDao screenDao = (ScreenDao)AppSpringBridge.getApplicationContext().getBean("screenDaoImpl");

I fixed it, and for posterity's sake I'll post my solution here:

First I autowired my screenDao bean in the invoking class, and then I created a static method to set screenDao.

@Autowired
private static ScreenDao screenDao;

@PostConstruct
public static void setScreenDao(ScreenDao newScreenDao) {
    screenDao = newScreenDao;
}

@PostConstruct
public ScreenDao getScreenDao() {
    return screenDao;
}

I'm not really sure if getScreenDao does anything but I added it as well.

Then in my application context I created a bean I called initialize to invoke the static method.

<bean id="initialize" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass" value="com.corp.apps.consolidator.backing.ScreenBean"/>
    <property name="targetMethod" value="setScreenDao"/>
    <property name="arguments">
        <list>
            <ref bean="screenDao"/>
        </list>
    </property>
</bean>

These two changes resolved my issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM