NullPointerException with #Inject and #PostPersist Method - jpa

After an entity is persisted, I want to execute a Bean, which sends a registration Mail to the newly registered user. I want to do this with a Listener class. I did the following:
Annotated the Entity with #EntityListener (UserListener.class)
Created the Listener and annotated it with #Stateless
Here is the code of the listener:
( the system.out.println part is just for testing purposes)
#Stateless
public class UserListener {
#Inject
private MailSenderController mailSenderController;
#PostPersist
void onPostPersist(User user) throws AddressException{
System.out.println("PostPersist");
System.out.println("Username: " + user.getUsername());
mailSenderController.sendRegistrationMail(user);
}
}
The MailSenderController is a #RequestScoped annotated Bean.
If I execute the code, I get a NullPointerException.
If I remove mailSenderController.sendRegistrationMail(user), the code works fine.
I think the onPostPersist gets executed before the MailSenderController gets injected and this causes the NullPointerException.
Can someone help me out with this problem?

I am guessing that MailSenderController is not the entry point of your user registration entry point. If yes then MailSenderController is always going to be NULL. Considering the MailSenderController has request scope, DI framework would only instantiate the controller processing HTTP request for sending mail.
From design point of view its not good to call your controller directly from DAO layer classes. I think you need to create a new managed bean (single instance) MailSenderService and then inject the new service instead of accessing a request scoped controller.

just add #Named annotation to MailSenderController

Related

DI and inheritance

Another question appeared during my migration from an E3 application to a pure E4.
I got a Structure using inheritance as in the following pic.
There I have an invocation sequence going from the AbstractRootEditor to the FormRootEditor to the SashCompositeSubView to the TableSubView.
There I want to use my EMenuService, but it is null due to it can´t be injected.
The AbstractRootEditor is the only class connected to the Application Model (as a MPart created out of an MPartDescriptor).
I´d like to inject the EMenuService anyway in the AbstractSubView, otherwise I would´ve the need to carry the Service through all of my classes. But I don´t have an IEclipseContext there, due to my AbstractSubView is not connected with Application Model (Do I ?).
I there any chance to get the service injected in the AvstractSubView?
EDIT:
I noticed that injecting this in my AbstractSubView isn´t possible (?), so I´m trying to get it into my TableSubView.
After gregs comment i want to show some code:
in the AbstractRootEditor:
#PostConstruct
public final void createPartControl(Composite parent, #Active MPart mPart) {
...
ContextInjectionFactory.make(TableSubView.class, mPart.getContext());
First I got an Exception, saying that my TableSubView.class got an invalid constructor, so now the Constructor there is:
public TableSubView() {
this.tableInputController=null;
}
as well as my Field-Injection:
#Inject EMenuService eMenuService
This is kind of not working, eMenuService is still null
If you create your objects using ContextInjectionFactory they will be injected. Use:
MyClass myClass = ContextInjectionFactory.make(MyClass.class, context);
where context is an IEclipseContext (so you have to do this for every class starting from one that is injected by Eclipse).
There is also a seconds version of ContextInjectionFactory.make which lets you provide two contexts the second one being a temporary context which can contain additional values.

Does Guice Persist provide transaction scoped or application managed EntityManager?

We use Guice Persist to inject EntityManager in our project.
E.g.
public class MyDao{
#Inject
EntityManager em;
public void someMethod(){
//uses em instance
}
}
But it is unclear for us how injected instance of EntityManager is about to be used.
What type of EntityManager is this? (see e.g.: types of entity managers) Under the hood Guice Persist instantiates it via EntityManagerFactory.createEntityManager() so I'd say it's application-managed entity manager. But in official Wiki they write about seesion-per-transaction strategy, which suggests that EntityManager is (pseudo) transaction-scoped.
Should we invoke close() on it manually? Or Guice will take care of it?
What is the scope of first level cache? Only single transaction (like in transaction-scoped entity managers) or as long as I use the same injected instance of EntityManager (like in application managed entity managers)?
Even though the question is perfectly answered by Piotr I'd like to add some practical advise on how to use guice-persist.
I've been having issues with it which were pretty hard to debug. In my application certain threads would display outdated data and sometimes EntityManager instances were left with old dead database connections. The root cause was to be found in the way I used the #Transactional annotation (I only used them for methods that do updates/inserts/deletes, not for read-only methods). guice-persist stores EntityManager instances in a ThreadLocal as soon as you call get() on an injected Provider<EntityManager> instance (which I did for read-only methods). However, this ThreadLocal is only removed if you also call UnitOfWork.end() (which normally is done by the interceptor if #Transactional is on the method). Not doing so will leave the EM instance in the ThreadLocal so that eventually every thread in your thread pool will have an old EM instance with stale cached entities.
So, as long as you stick to the following simple rules the usage of guice-persist is straight forward:
Always inject Provider<EntityManager> instead of EntityManager directly.
For transaction-scoped semantics: always annotate each method with #Transactional (even the read-only methods). This way the JpaLocalTxnInterceptor will intercept the calls to your annotated methods making sure not only to start and commit transactions but also to set and unset EM instances in the ThreadLocal.
For request-scoped semantics: use the PersistFilter servlet filter that ships with guice-persist. It will call begin() and end() on the UnitOfWork for you before and after the request is done, thereby populating and cleaning up the ThreadLocal.
Hope this helps!
I did some research of the source code of Guice-persist and read through comments under Guice-persist wiki pages and these are the answers that I needed:
1 . Lifecycle management of EntityManager is kind of broken if it's injected via #Inject EntityManager. As stated in one of the comments on the Wiki:
I confirm that inject directly an EntityManager instead of a provider
can be dangerous. If you're not inside a UnitOfWork or a method
annotated with #Transaction, the first injection of an EntityManager
in a thread will create a new EntityManager, never destroy it, and
always use this specific EntityManager for this thread (EM are stored
thread-local). This can lead to terrible issues, like injection of
dead entityManager (connection closed, etc) So my recommendation if to
always inject a Provider, or at least to inject
directly an EntityManager only inside an opened UnitOfWork.
So example in my question isn't the most correct usage. It creates singleton instance of EntityManager (per-thread) and will inject this instance everywhere :-(.
However if I've injected Provider and used it inside #Transactional method then the instance of EntityManager would be per-transaction. So the answer to this question is: if injected and used correctly, the entity manager is transaction-scoped.
2 . If injected and used correctly then I don't need to manualy close entity manager (guice-persist will handle that for me). If used incorrectly, closing manually would be very bad idea (closed instance of EntityManager would be injected in every place when I #Inject EntityManager )
3 . If injected and used correctly then the scope of L1 cache is single transaction. If used incorrectly, the scope of the L1 cache is the lifetime of application (EntityManager is singleton)
1. It depends on you module cofiguration. There are some basic bindings:
JpaPersistanceService
public class JpaPersistanceService implements Provider<EntityManager> {
private EntityManagerFactory factory;
public JpaPersistanceService(EntityManagerFactory factory) {
this.factory = factory;
}
#Override
public EntityManager get() {
return factory.createEntityManager();
}
}
Module binding
EntityManagerFactory factory = Persistence.createEntityManagerFactory(getEnvironment(stage));
bind(EntityManager.class).annotatedWith(Names.named("request")).toProvider(new JpaPersistanceService(factory)).in(RequestScoped.class);
bind(EntityManager.class).annotatedWith(Names.named("session")).toProvider(new JpaPersistanceService(factory)).in(SessionScoped.class);
bind(EntityManager.class).annotatedWith(Names.named("app")).toProvider(new JpaPersistanceService(factory)).asEagerSingleton;
Usage
#Inject #Named("request")
private EntityManager em; //inject a new EntityManager class every request
#Inject #Named("session")
private Provider<EntityManager> emProvider; //inject a new EntityManager class each session
//This is little bit tricky, cuz EntityManager is stored in session. In Stage.PRODUCTION are all injection created eagerly and there is no session at injection time. Session binding should be done in lazy way - inject provider and call emProvider.get() when em is needed;
#Inject #Named("application")
private EntityManager em; //inject singleton
2. Yes, you should or you will use JpaPersistModule [javadoc]
3. Well, this is about JPA configuration in persistence.xml and EntityManager scope
I'm injecting a provider .... but I suspect something is wrong.
When I try to redeploy an application ALWAYS I have to restar the server because the JPA classes are cached.
It happens the following pseudo-bug
https://bugs.eclipse.org/bugs/show_bug.cgi?id=326552
Theoretically by injecting a Provider and getting an instance of EntityManager you should not close anything ....

GIN #Inject on variable for Rpc Services

I'm a bit lost with the use of Inject on variable.
I got this code working :
private XXServiceAsync xxServiceAsync;
#Inject
protected IndexViewImpl(EventBus eventBus, XXServiceAsync tableManagementServiceAsync) {
super(eventBus, mapper);
this.xxServiceAsync = xxServiceAsync;
initializeWidgets();
}
With this code, I can call my RPC service wherever I need in the class (On click ...)
I would like to clear a bit the code by injecting direcly in the variable ; doing so :
#Inject
private XXServiceAsync xxServiceAsync;
protected IndexViewImpl(EventBus eventBus) {
super(eventBus, mapper);
initializeWidgets();
}
This always keep the Service to NULL.
Am I doing something wrong ? Is the GIN magic with rpc services meant to be done otherwise?
Thanks!
It is still null at that point, because Gin (and Guice, and other frameworks like this) cannot assign the fields until the constructor has finished running.
Consider how this would look if you were manually wiring the code (remember that Gin/Guice will cheat a little to assign private fields, call non-visible methods):
MyObject obj = new MyObject();//initializeWidgets() runs, too early!
obj.xxServiceAsync = GWT.create(xxService.class);
If you need something in the constructor, pass it into the constructor. If you wont need it right away (such as until asWidget() is called), then a field or setter annotated with #Inject can be helpful.
If you have field level injection you can use an empty #Inject method to do your post-inject initialization. The no-arg injected method will be run after field injections on the class are complete.
#Inject void initialize(){
...
initializeWidgets()
}
Edit: I previously stated that it was run after method injection as well, but testing shows that this is not always the case.

ObjectDisposedException thrown everytime a "User" (membership) object is updated

I am using asp.net mvc 3, entity framework with structure map for IoC.
I have my own custom membership provider.
I had the same kind of problem when I was injecting the dbcontext object and the membership instances using StructureMap so removed this for my UserRepository.
The UserRepository now has a DBContext property which is initialised in the constructor.
Everytime a new user is created/updated (the method doing this is wrapping the dbcontext object in using statement), the next time the dbcontext is referenced I get ObjectDisposedException thrown.
I don't understand what I am doing wrong. Obviously, the membership provider class isn't instantiating the userRepository object everytime it needs it and when a user is updated, the context is disposed because of the using statement. But I thought this was standard practice?
Any help is greatly appreciated.
EDITED:
There is no complex code really. The set up is:
CustomMembershipProvider overrides the standard Membership provider (config file has got the details).
CustomMembershipProvider uses IUserService object that uses IUserRepository which is implemented by UserRepository that has the DBContext private object at class level.
In the UserRepository, I've got:
public void UpdateUser(User user)
{
using(_db)
{
... code to indicate that the user state has changed
_db.SaveChanges();
}
}
Once this code is run, the request is complete. But when another request is made to retrive role information or read the user from the database (in the UserRepository class), I get the ObjectDisposedException thrown. At this point nothing related to User Or Role works because they use the same UserRepository class whose _db variable has been disposed by UpdateUser.
I initially had StructureMap resolve the DBContext object, the customMembership object etc but have had to since remove it from StructureMap's mapping.
Everytime a new user is
created/updated (the method doing this
is wrapping the dbcontext object in
using statement), the next time the
dbcontext is referenced I get
ObjectDisposedException thrown.
DbContext is a disposable resource(Which implements IDisposable). So when you wrap it in a using block the context is disposed when the control flow goes out of the using block.
using(myContext)
{
//do stuff
}
//try to access myContext after the using block throw ObjectDisposedException
You have to re-design how you use the DbContext and when you are going to dispose it.

Creating new entities while enabling injection

I have a method on a stateless session bean which creates a new instance of an entity and persists it. You might normally use new MyEntity() to create the object but I would like injection to populate some of the properties of the entity for me.
I got partial success using
#Inject
#New
private MyEntity myNewEntity;
in the session bean and then using that instance in my method.
The problem I have now is that the second time the method is called, myNewEntity isn't a new object, its the same object as the one created the first time. As a result I'm getting
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '9' for key 'PRIMARY'
Or at least that's why I think I'm getting this exception. Certainly if I use new MyEntity() I don't get the exception but my injection doesn't happen.
Am I on the wrong track? How can I create a new local entity object while enabling injection?
Any help would be great!
First of all - I have serious doubts that it's a good idea to use CDI to control the lifecycle of a Entity. See this quote from the documentation (here):
According to this definition, JPA
entities are technically managed
beans. However, entities have their
own special lifecycle, state and
identity model and are usually
instantiated by JPA or using new.
Therefore we don't recommend directly
injecting an entity class. We
especially recommend against assigning
a scope other than #Dependent to an
entity class, since JPA is not able to
persist injected CDI proxies.
What you should do to create new instances of entities is adding a layer of indirection, either with #Produces or #Unwraps (Seam Solder, if you need it to be truly stateless), and thereby making sure that you code explicitly calls new.
I think I have a working solution now which seems okay, though I'm not quite sure why it works so I welcome your feedback on a better solution. I am now injecting a DAO-style bean into my stateless session bean:
#Stateless
public class PhoneService {
#Inject
protected ProblemReports problemReports;
An injecting my entity into the ProblemReports bean:
public class ProblemReports {
#Inject
#New
private ProblemReport newProblemReport;
I assume that ProblemReports defaults to #Dependant scope which as I understand it should be the same as the stateless session bean which containts it. I could understand this if the scope of ProblemReports was shorter, causing a new instance of ProblemReport to be created when the new ProblemReports is created; but it isn't.
Is this just an example of EJB and CDI not playing well together?