1

我最近从使用 JSF2 切换到使用 CDI/weld。我有 2 个渴望的 @ManagedBeans(eager=true),其中一个有一个使用数据库查询 (JPA 2) 填充的列表。它工作得很好。

我切换到 CDI 并使用此处描述的技术重构了这些 bean http://ovaraksin.blogspot.com/2013/02/eager-cdi-beans.html。它适用于在 @PostConstruct init() 期间手动填充列表的 bean,但挂在填充列表的 bean 上,因为它正在注入使用数据库查询的服务。

它把东西挂得太厉害了,我不得不杀死服务器!

为什么会这样,除了让那个豆子不急切之外,还有其他方法吗?如果必须的话,我可以让豆子“不急”。我只是想知道我误解了什么。

这是挂着的豆子,它是后端

OsList.java:

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.jboss.logging.Logger;

@Eager
@ApplicationScoped
@Named
public class OsList {

    Logger log = Logger.getLogger(OsList.class);

    private List<String> osList = new ArrayList<String>();

    @Inject 
    OsListService osService;

    public OsList() {}

    @PostConstruct
    public void init(){
        log.info("Creating the one and only OsList bean");
        osList = osService.fetchOs();
    }

    public List<String> getOsList() {
        return osList;
    }

    public void setOsList(List<String> osList) {
        this.osList = osList;
    }

OsListService.java:

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.jboss.logging.Logger;

import dne.nmst.dac.model.Devices;
import dne.nmst.dac.model.Devices_;

@Stateless
public class OsListService {

    Logger log = Logger.getLogger(OsListService.class);

    @PersistenceContext
    EntityManager em;

    public List<String> fetchOs() {
        log.info("Do we ever get here?");
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<String> cq = cb.createQuery(String.class);
        Root<Devices> d = cq.from(Devices.class);

        cq.select(d.get(Devices_.os));
        cq.distinct(true);
        cq.orderBy(cb.asc(d.get(Devices_.os)));

        TypedQuery<String> q = em.createQuery(cq);

        List<String> iosList = new ArrayList<String>();
        iosList.add("");
        for (String s : q.getResultList()) {
            iosList.add(s);
        }
        return iosList;

    }

日志文件

11:14:43,569 INFO  [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) JBAS015003: Found ond-cdi.war in deployment directory. To trigger deployment create a file called ond-cdi.war.dodeploy
11:14:43,590 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-8) JBAS015876: Starting deployment of "ond-cdi.war" (runtime-name: "ond-cdi.war")
11:14:45,330 INFO  [org.jboss.as.jpa] (MSC service thread 1-5) JBAS011401: Read persistence.xml for ond
11:14:45,731 INFO  [org.jboss.weld.deployer] (MSC service thread 1-7) JBAS016002: Processing weld deployment ond-cdi.war
11:14:45,781 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-7) JNDI bindings for session bean named OsListService in deployment unit deployment "ond-cdi.war" are as follows:

    java:global/ond-cdi/OsListService!gov.ssa.dne.nmst.service.OsListService
    java:app/ond-cdi/OsListService!gov.ssa.dne.nmst.service.OsListService
    java:module/OsListService!gov.ssa.dne.nmst.service.OsListService
    java:global/ond-cdi/OsListService
    java:app/ond-cdi/OsListService
    java:module/OsListService

11:14:45,781 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-7) JNDI bindings for session bean named DeviceService in deployment unit deployment "ond-cdi.war" are as follows:

    java:global/ond-cdi/DeviceService!gov.ssa.dne.nmst.service.DeviceService
    java:app/ond-cdi/DeviceService!gov.ssa.dne.nmst.service.DeviceService
    java:module/DeviceService!gov.ssa.dne.nmst.service.DeviceService
    java:global/ond-cdi/DeviceService
    java:app/ond-cdi/DeviceService
    java:module/DeviceService

11:14:46,071 INFO  [org.jboss.weld.deployer] (MSC service thread 1-7) JBAS016005: Starting Services for CDI deployment: ond-cdi.war
11:14:46,121 INFO  [org.jboss.weld.Version] (MSC service thread 1-7) WELD-000900 1.1.13 (redhat)
11:14:46,151 INFO  [org.jboss.weld.deployer] (MSC service thread 1-5) JBAS016008: Starting weld service for deployment ond-cdi.war
11:14:46,151 INFO  [org.jboss.as.jpa] (ServerService Thread Pool -- 48) JBAS011402: Starting Persistence Unit Service 'ond-cdi.war#ond'
11:14:46,281 INFO  [org.hibernate.annotations.common.Version] (ServerService Thread Pool -- 48) HCANN000001: Hibernate Commons Annotations {4.0.1.Final-redhat-2}
11:14:46,281 INFO  [org.hibernate.Version] (ServerService Thread Pool -- 48) HHH000412: Hibernate Core {4.2.0.Final-redhat-1}
11:14:46,281 INFO  [org.hibernate.cfg.Environment] (ServerService Thread Pool -- 48) HHH000206: hibernate.properties not found
11:14:46,281 INFO  [org.hibernate.cfg.Environment] (ServerService Thread Pool -- 48) HHH000021: Bytecode provider name : javassist
11:14:46,301 INFO  [org.hibernate.ejb.Ejb3Configuration] (ServerService Thread Pool -- 48) HHH000204: Processing PersistenceUnitInfo [
    name: ond
    ...]
11:14:46,621 INFO  [org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator] (ServerService Thread Pool -- 48) HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
11:14:46,842 INFO  [org.hibernate.dialect.Dialect] (ServerService Thread Pool -- 48) HHH000400: Using dialect: org.hibernate.dialect.MySQLInnoDBDialect
11:14:46,862 INFO  [org.hibernate.engine.transaction.internal.TransactionFactoryInitiator] (ServerService Thread Pool -- 48) HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory
11:14:46,862 INFO  [org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory] (ServerService Thread Pool -- 48) HHH000397: Using ASTQueryTranslatorFactory
11:14:46,892 INFO  [org.hibernate.validator.internal.util.Version] (ServerService Thread Pool -- 48) HV000001: Hibernate Validator 4.3.1.Final-redhat-1
11:14:47,592 INFO  [org.jboss.solder.config.xml.bootstrap.XmlConfigExtension] (MSC service thread 1-6) Solder Config XML provider starting...
11:14:47,592 INFO  [org.jboss.solder.config.xml.bootstrap.XmlConfigExtension] (MSC service thread 1-6) Loading XmlDocumentProvider: org.jboss.solder.config.xml.bootstrap.ResourceLoaderXmlDocumentProvider
11:14:47,602 INFO  [org.jboss.solder.config.xml.bootstrap.XmlConfigExtension] (MSC service thread 1-6) Reading XML file: vfs:/D:/work/software/jboss-eap-6.1/standalone/deployments/ond-cdi.war/WEB-INF/beans.xml
11:14:47,612 INFO  [org.jboss.solder.Version] (MSC service thread 1-6) Solder 3.1.1.Final (build id: 3.1.1.Final)
11:14:48,422 INFO  [gov.ssa.dne.nmst.util.OsList] (MSC service thread 1-6) Creating the one and only OsList bean
4

2 回答 2

0

老实说,我不知道你为什么要这样做。CDI 的一部分是您的 bean 不会比它们需要的寿命更长。为了轻松迁移,我只需为您的 bean 找到正确的范围(ApplicationScoped 通常是错误的范围)并在@PostConstruct方法中执行您需要的操作。

我对正在发生的事情的猜测是,您正在为创建 EJB 的时间与 CDI bean 需要注入它的时间以及它们相互阻塞的时间发生争用。不过,我没有任何确凿的证据支持这一点。

于 2013-06-26T23:05:15.257 回答
0

避免该问题的一种可能方法是使用带有 @Startup 注释的 Singleton-EJB。并没有真正解决问题。

import javax.ejb.Singleton;
...

@Singleton
@Startup
public class OsListService {

    Logger log = Logger.getLogger(OsListService.class);

    @PersistenceContext
    EntityManager em;

    private List<String> iosList;

    @PostConstruct
    public void init() {


        this.iosList = ... //result from your query
    }

    public List<String> fetchOs() {
        return this.iosList;
    }
}
于 2013-06-25T18:08:51.287 回答