I'm trying to make a program work in vaadin & spring-boot, but can't make EntityManager work. Getting a NullReferenceException
For starters, this is my firs try making something using Spring-boot and Vaadin. I am trying to make EntityManager work, but I'm getting a NullReferenceException. It seems my EntityManager is throwing the exception, but I can't find any examples on how to use it properly. I thought about using EntityManagerFactory, but again, no examples anywhere.. The findAll() method works, so I'm not sure what to do.
I have a Repository_Room interface
public interface Repository_Room
{
void save(Room room);
void delete(Room room);
void update(Room room);
List<Room> findAll();
List<Course> getCourses(Room room);
}
Implementing it in Repository_Room_Impl class
@Transactional
@Repository
public class Repository_Room_Impl implements Repository_Room{
@PersistenceContext
private EntityManager em;
public Repository_Room_Impl()
{
}
@Override
public List<Room> findAll() {
return em.createQuery("select n from " + Room.class.getSimpleName() + " n").getResultList();
}
@Override
public void save(Room room) {
em.persist(room);
}
public void delete(Room room) {
em.remove(em.find(Room.class, room.getId()));
}
public void update(Room room) {
em.merge(em);
}
public List<Course> getCourses(Room room)
{
List<Course> courses = em.createQuery("select n from " + Course.class.getSimpleName() + " n WHERE n.Room = :roomID", Course.class)
.setParameter("roomID", room.getId())
.getResultList();
return courses;
}
}
Trying to use the repository in my form to add a new element
@SpringComponent
@UIScope
public class Form_Room extends VerticalLayout {
private Room room;
private Reloader reloader;
private TextField val_id;
private TextField val_name;
private TextField val_level;
private Binder<Room> binder;
@Autowired
private Repository_Room repository;
public Form_Room()
{
binder = new Binder<>(Room.class);
val_id = new TextField("ID:");
val_name = new TextField("Name:");
val_level = new TextField(("Level:"));
binder.forField(val_id)
.withConverter(
new StringToIntegerConverter("Must enter a number"))
.bind(Room::getId, Room::setId);
binder.forField(val_name).bind(Room::getName, Room::setName);
binder.forField(val_level)
.withConverter(
new StringToIntegerConverter("Must enter a number"))
.bind(Room::getLevel, Room::setLevel);
add(val_id);
add(val_name);
add(val_level);
}
public Room getRoom() {
return room;
}
public void setRoom(Room room) {
if (room == null) {
this.room = null;
}
else {
this.room = room;
binder.readBean(this.room);
}
}
public Reloader getReloader() {
return reloader;
}
public void setReloader(Reloader reloader) {
this.reloader = reloader;
}
public void updateRoom()
{
try
{
if(room == null)
{
repository.save(this.room);
System.out.println("Created");
}
else
{
binder.writeBean(this.room);
repository.update(this.room);
System.out.println("Updated");
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
This form is created in my view
@Route(value = "rooms")
public class View_CRUD_Room extends VerticalLayout implements Reloader{
@Autowired
private Repository_Room repository;
@Autowired
private Form_Room form;
private Grid<Room> grid;
private Button button_view;
private Button button_remove;
private Button button_execute;
private HorizontalLayout buttonLayout;
private Room selected;
@PostConstruct
private void init(){
form = new Form_Room();
grid = new Grid<>();
button_view = new Button();
button_remove = new Button();
buttonLayout = new HorizontalLayout();
selected = null;
button_execute = new Button();
button_execute.setText("Végrehajt");
button_view.setText("Részletek");
button_remove.setText("Töröl");
buttonLayout.add(button_view);
buttonLayout.add(button_remove);
form.setVisible(true);
button_execute.addClickListener(event -> {
form.updateRoom();
});
button_view.addClickListener(event -> {
// Display details
});
button_remove.addClickListener(event -> {
// Display form with confirmation message and YesNo buttons
});
List<Room> list = repository.findAll();
grid.setItems(repository.findAll());
grid.addColumn(Room::getId).setHeader("Id");
grid.addColumn(Room::getName).setHeader("Name");
grid.addColumn(Room::getLevel).setHeader("Terem");
grid.asSingleSelect().addValueChangeListener(selectionEvent -> {
if (selectionEvent.getValue() != null) {
selected = selectionEvent.getValue();
form.setRoom(selected);
} else {
selected = null;
form.setRoom(selected);
}
});
add(new Text("Termek"));
add(grid);
add(buttonLayout);
add(form);
add(button_execute);
}
@Override
public void processRefresh() {
grid.setItems(repository.findAll());
}
}
The stackTrace prints the following:
java.lang.NullPointerException
at com.example.beadando.repository.Impl.Repository_Room_Impl.save(Repository_Room_Impl.java:26)
at com.example.beadando.component.Form_Room.updateRoom(Form_Room.java:93)
at com.example.beadando.view.View_CRUD_Room.lambda$init$9b1b5227$1(View_CRUD_Room.java:55)
at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:205)
at com.vaadin.flow.component.ComponentEventBus.handleDomEvent(ComponentEventBus.java:373)
at com.vaadin.flow.component.ComponentEventBus.lambda$addDomTrigger$dd1b7957$1(ComponentEventBus.java:264)
at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$2(ElementListenerMap.java:420)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:420)
at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:59)
at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:64)
at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:387)
at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$1(ServerRpcHandler.java:368)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:368)
at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:310)
at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89)
at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1507)
at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:242)
at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:81)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
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)
I modified the setRoom() method to try to add a new element without having to deal with my TextFields. Getting NullReferenceException in the form when trying to call my updateRoom() method. Please point me in the right direction.. Thank you!
Sorry i was a bit too fast when looking before.
But this is your problem, you are creating the autowired classes yourself instead of letting Spring create them for you.
@Autowired
private Repository_Room repository;
public Form_Room() {
repository = new Repository_Room_Impl(); //remove this line
//rest of the code
}
And here you do it again in your view:
@Route(value = "rooms")
public class View_CRUD_Room extends VerticalLayout implements Reloader {
@PostConstruct
private void init(){
form = new Form_Room(); //remove this line
//rest of the code
}
You see autowire is something called Dependency Injection. This is a fancy word for saying that "the framwork" (in this case spring) will do all the instantiation of classes for you.
Spring will do the "new" for you. And inject in a class during runtime for you to use so you dont have to. Spring will also before it does a "new RepositoryImpl()" will check what dependencies that class has and see that it needs an EntityManager, and instantiate one automagically for you and put that into the RepositoryImpl.
Thats the whole point of using Autowire, that you dont have to do the new. You just have to trust that there will be class there when you use it.
Then some other pointers about your code.
In java we use camel caseing so instead of "Repository_Room" it should be "RepositoryRoom" same goes for "Repository_Room_Impl" should be "RepositoryRoomImpl"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With