3

I am studying/experimenting with EJBs. I have an EJB with an overridden toString method:

@Stateless
@LocalBean
public class FlightService {
... 
@Override
public String toString() {
    return "FlightService [id=" + id + ", from=" + from + ", to=" + to + ", price=" + price + ", airplaneModel="
            + airplaneModel + "]";
}

}

In my servlet, I inject this EJB into a variable, like this:

@EJB
private FlightService fs;

However, when I would like to print it out..

if (fs != null){
    out.println("Flight details: " + fs.toString());
}

.. I get the following output, which is what I would get with the defaul toString method, I think.

Flight details: com.airline.service.__EJB31_Generated__FlightService__Intf___754270295

Instead of

Flight details: FlightService [id=123, ...]

as I would expect. All other functionalities of the EJB are working as expected, as far as I can tell. Can someone please explain to me what happens with the toString method? Thank you!

EDIT: It works with explicitly created objects (new FlightService()), as suggested by Soumitri Pattnaik.

EDIT2: Full source available on pastebin. FlightService.java, FlightDetails.java The project was created in Eclipse, running on Glassfish 4.

b4kancs
  • 105
  • 8
  • 1
    what type are the elements you are trying to print? also, you don't have to put fs.toString(), when putting fs in a print statement, it will automatically call the toString method – Stultuske Mar 08 '16 at 09:40
  • 1
    Check the type of the actual `fs` object, it may be of some other class or interface. And that might be the reason of different `toString()` call. – Soumitri Pattnaik Mar 08 '16 at 09:42
  • @Stultuske They are just some local int and String variables I handle with getters and setters. "it will automatically call the toString method", thanks, I wasn't sure about that. I get the same result, though. – b4kancs Mar 08 '16 at 09:43
  • 1
    @Soumitri Pattnaik It is of the type FlightService, which I think is what it should be. – b4kancs Mar 08 '16 at 09:47
  • 1
    @b4kancs as you are not explicitly creating the object by `new` keyword, there is a chance that, the actual object is of a child / parent type. – Soumitri Pattnaik Mar 08 '16 at 09:49
  • 1
    @Soumitri Pattnaik I see. I thought I wasn't supposed to do that with EJBs. I also tried to look it up through JNDI with the same results. I will try some things now. – b4kancs Mar 08 '16 at 09:52
  • @b4kancs good luck buddy – Soumitri Pattnaik Mar 08 '16 at 09:53
  • 1
    @Soumitri Pattnaik It indeed works with a new FlightService() object. I will try to find out what happens in the background now. Thanks! – b4kancs Mar 08 '16 at 09:59
  • 1
    In the future, please don't use [java] tag as long as problem is not reproducible with a plain Java application class with `main()` method. You'll otherwise get a lot of noise, blind guesses and possibly completely wrong answers from those [java] users. – BalusC Mar 08 '16 at 10:21
  • @BalusC Thanks, got it! – b4kancs Mar 08 '16 at 11:09
  • Your EJB toString method is fundamentally flawed anyway. Your EJB is annotated @Stateless, therefore your toString method may be called on a different instance of the bean than the one that has the state that you specified. – Steve C Mar 09 '16 at 13:05
  • @SteveC Yeah, I got that. I was just experimenting. Thanks! – b4kancs Mar 11 '16 at 09:45

1 Answers1

1

@EJB doesn't inject an actual instance. @EJB injects an autogenerated proxy instance which locates the actual instance in the pool and delegates to it. Depending on the EJB implementation used (read: depending on the appserver used), the autogenerated proxy class may have its own toString() which may or may not use your toString(). Yours apparently completely ignores it.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • "an autogenerated proxy instance" - I didn't know about this part, thanks! It's much clearer now. – b4kancs Mar 08 '16 at 11:10
  • The client just uses the proxy with the implemented interface to communicate with the container, not the concrete implementation class. And then the container calls the concrete instance within the prepared context (security, transaction, etc) – The Bitman Mar 12 '16 at 17:12
  • @TheBitman: indeed, see also the "See also" link for a concrete example. – BalusC Mar 12 '16 at 18:26