I'm developing little app and have some issues with DI.
I have a repository class for persisting my entities which I inject to my service. And I'd like to inject Session object to it using H2K. For this purpose I try do something similar described in following SO posts:
- Jersey + HK2 + Grizzly: Proper way to inject EntityManager?
- Using Jersey 2.0, how do you register a bindable instance per request?
- How do I properly configure an EntityManager in a jersey / hk2 application?
So I created SFFactory class and register it in ApplicationConfig.
SFFactory.java
import org.glassfish.hk2.api.Factory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class SFFactory implements Factory<Session> {
private SessionFactory factory;
public SFFactory() {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
StandardServiceRegistryBuilder srBuilder = new StandardServiceRegistryBuilder();
srBuilder.applySettings(configuration.getProperties());
factory = configuration.buildSessionFactory(srBuilder.build());
}
@Override
public Session provide() {
return factory.openSession();
}
@Override
public void dispose(Session session) {
if (session.isOpen()) {
session.close();
}
}
}
ApplicationConfig.java
import org.alexdzot.phonettesttask.repository.MessageRepository;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.hibernate.Session;
import javax.inject.Singleton;
import javax.ws.rs.ApplicationPath;
@ApplicationPath("/rest/*")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
packages("org.alexdzot.phonettesttask");
register(new AbstractBinder() {
@Override
protected void configure() {
bindFactory(SFFactory.class).to(Session.class);
bindFactory(MessageRepositoryFactory.class).to(MessageRepository.class).in(Singleton.class);
}
});
}
}
DefaultMessageRepository
import org.alexdzot.phonettesttask.model.Message;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.jvnet.hk2.annotations.Service;
import javax.inject.Inject;
import java.util.List;
@Service
public class DefaultMessageRepository implements MessageRepository {
@Inject
private Session session;
public void saveMessage(Message message) {
Session session = null;
Transaction tx = null;
try {
tx = session.beginTransaction();
session.save(message);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
public List<Message> getAllMessages() {
Session session = null;
Transaction tx = null;
List<Message> messages = null;
try {
tx = session.beginTransaction();
messages = session.createCriteria(Message.class).list();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
return messages;
}
}
}
But when I run the app and trying to call repository methods I get NullPoinerException. I can't understand what am I doing wrong. This is what Tomcat log is saying:
*08-Aug-2015 02:42:18.232 SEVERE [http-nio-8080-exec-10] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [org.alexdzot.phonettesttask.config.ApplicationConfig] in context with path [] threw exception [java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at org.alexdzot.phonettesttask.repository.DefaultMessageRepository.getAllMessages(DefaultMessageRepository.java:42)
at org.alexdzot.phonettesttask.service.MessageResource.viewSentMessages(MessageResource.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:308)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:291)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1140)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:403)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:334)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)*
Any ideas what wrong with my solution and what causes that problem?