【问题标题】:Data seem to vansih between EJB and CDI beanEJB 和 CDI bean 之间的数据似乎消失了
【发布时间】:2015-10-09 17:01:54
【问题描述】:

我的 Java EE 7 CDI BackingBean,通过 EJB 从 DB 获取数据。 EJB 获取正确的数据并将列表(例如 3 个项目)返回给 BackingBean。 BackingBean 获得 3 个项目,但所有数据字段都是 0null

BackingBean:

@Named
@RequestScoped
public class AddActuatorController implements Serializable {
   ...
   @EJB
   protected SensorBeanRemote sensorBean;
   ...
   protected List<Sensor> allSensors;
   ...
   @PostConstruct
   private void init() {
      ...
      logger.info("try to get sensors ... ");
      allSensors=sensorBean.getSensors();
      logger.info("got <"+allSensors.size()+"> sensors");

      Iterator<Sensor> iter=allSensors.iterator();
      Sensor s;
      while(iter.hasNext()){
          s=iter.next();
          logger.info(">>> [" + s.getId()+", "+s.getName()+", +s.getDescription()+"]");
      }
      ...
   }
   ...
}

EJB:

@Stateless
public class SensorBean implements SensorBeanRemote, SensorBeanLocal {

    @PersistenceContext
    protected EntityManager em;     
    ...
    @Override
    public List<Sensor> getSensors() {
        List<Sensor> sensorList=null;
        try{
            logger.info("try to load sensors from db ...");
            sensorList=em.createNamedQuery("Sensor.FindAll", Sensor.class).getResultList();
            logger.info("Found <"+sensorList.size()+"> sensors");

            Iterator<Sensor> iter=sensorList.iterator();
            Sensor s;
            while(iter.hasNext()){
                s=iter.next();
                logger.info(">>> [" + s.getId()+", "+s.getName()+", "+s.getDescription()+"]");
            }

            return sensorList;
        }catch(Exception e){
            logger.severe("Exception: <"+e.getLocalizedMessage()+">");
        }
        return null;
    }
}

在日志文件中我得到了:

2015-10-09T18:01:14.094+0200 ... try to get sensors ... 
2015-10-09T18:01:14.102+0200 ... try to load sensors from db ...
2015-10-09T18:01:14.384+0200 ... Found <3> sensors
2015-10-09T18:01:14.385+0200 ... 6, huette1, Sensor in der Huette 1
2015-10-09T18:01:14.385+0200 ... 8, huette2, Sensor 2 in Haus 1
2015-10-09T18:01:14.385+0200 ... 9, dfsdf, sdfsd]
2015-10-09T18:01:14.394+0200 ... got <3> sensors
2015-10-09T18:01:14.395+0200 ... 0, null, null
2015-10-09T18:01:14.395+0200 ... 0, null, null
2015-10-09T18:01:14.395+0200 ... 0, null, null

为什么所有数据字段都是null0

当我从 SensorBeanRemote 切换到 SensorBeanLocal 时,它工作正常。

传感器实体:

@Entity
@Table(schema="tp_smartHuette", name="sensor")
@NamedQueries({
    @NamedQuery(name="Sensor.FindAll", query="SELECT s FROM Sensor s"),
    ...
    })
public class Sensor extends AbstractElement implements Serializable {
    ...
}

传感器超类:

@MappedSuperclass
public abstract class AbstractElement implements Element {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected long id;

    @ManyToOne
    protected Location location; 

    @Basic
    protected String name;

    @Basic
    protected String description;

    @Basic
    protected String host;

    @Basic
    protected int port;

    @Basic
    protected String authentication;
    ...
}

这是我的第一个java ee项目,设计怪怪的,请耐心等待。

【问题讨论】:

  • 您也应该发布传感器实体类,或者至少发布带有注释等的属性。
  • @Local接口有同样的问题吗?
  • 您的实体类可能是从两个类路径加载的。因此,在设置它们的值时,类是从一个路径加载的(根据优先级在类路径中第一次出现)。但是当你获取时,类是从不同的路径加载的。只需确保只在一个地方上课。
  • Location 是否实现 java.io.Serializable?
  • 是的,Location 实现了java.io.Serializable。抱歉,我不明白“您的实体类可能是从两个类路径加载的”。目前,它只有一个 glassfish 服务器(@Local 可能就足够了)。

标签: jakarta-ee ejb cdi


【解决方案1】:

这看起来像是一个序列化问题。如果使用@Remote 接口,对象在被 EJB 返回之前会被序列化(因为它期望在不同的服务器上),而使用@Local 可以直接传递对象引用。

数据字段为空,因为AbstractElement不可序列化——在这种情况下,java序列化机制将序列化Sensor类中的字段,但通过调用父类的无参数构造函数构造一个新的超类,这会将超类的所有字段设置为默认值。

要修复它,只需让 AbstractElement 实现 Serializable

【讨论】:

  • 感谢您的解释。
猜你喜欢
  • 2015-02-12
  • 1970-01-01
  • 2018-07-13
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
  • 2012-04-20
相关资源
最近更新 更多