The dreaded Lazy Initialization Exception when using JAX-WS and JEE6
I am getting a LIE when using the JAX-WS @Path and the @Stateless (or @RequestScoped) annotation. The code:
@Path("/users")
@Stateless
@Produces(MediaType.APPLIC开发者_Go百科ATION_XML)
public class UserResourceRESTService {
@Inject
@UserRepository
@PersistenceContext
private EntityManager em;
@GET
@Path("/{id:[1-9][0-9]*}")
public User lookupUserById(@PathParam("id") long id) {
return em.find(User.class, id);
}
}
The actual exception I am getting:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
The user object has an address, which has a country. If I change this to a stateful bean and use an extended context it works, but this really shouldn't be a SFSB should it? I am at a bit of a loss as to why the "em" wouldn't be able to open a session when using a stateless bean?
When you are operating in extended persistence context your returned User entity remains in managed state and when you are using transaction persistence context transaction ends once lookupUserById() method returns and result of that method is an entity which is already detached from persistence context. As a result all properties of that entity which are marked as LAZY are not accessible anymore.
If you want to access these lazy properties after entity became detached from persistence context invoke specific getter methods on that entity prior returning from lookupUserById method.
i.e.
public User lookupUserById(@PathParam("id") long id) {
User user = em.find(User.class, id);
user.getAddress().getCountry();
return user;
}
You can also annotate your relationships in User class with fetch = FetchType.EAGER
. If you always return everything it's no point to have lazy loading in my opinion.
精彩评论