Search code examples
jakarta-eeejbcdi

Data seem to vansih between EJB and CDI bean


My Java EE 7 CDI BackingBean, fetches data from DB via a EJB. The EJB gets correct data and returns the list (e.g. 3 items) to the BackingBean. The BackingBean gets 3 items, but all datafields are 0 or null.

The 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()+"]");
      }
      ...
   }
   ...
}

The 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;
    }
}

In Logfile I got:

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

Why are all the datafields null or 0?

When I switch from SensorBeanRemote to SensorBeanLocal it works fine.

The Sensor Entity:

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

The Sensor Superclass:

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

This is my first java ee project, please be patient because of the strange design.


Solution

  • This looks like a serialisation problem. If you use the @Remote interface, objects are serialized before being returned by the EJB (because it expects to be on a different server), whereas with @Local the object references can be passed directly.

    The data fields are null because AbstractElement is not serializable - in this case, the java serialization mechanism will serialize the fields in the Sensor class, but construct a new superclass by calling the no-args constructor of the parent, which leaves all the fields of the superclass set to their defaults.

    To fix it, just make AbstractElement implement Serializable.