0

I have a problem with displaying values from database. I have:

@SpringUI(path="order")
public class OrderGUI extends UI 

with constructor:

public OrderGUI()
    {
        navigator = new Navigator(this, this);
        navigator.addView("GetOrderNumber", GetOrderNumber.class);
        navigator.addView("allpurchasers", AllPurchasersGUI.class);
    }

in GetOrderNumber class which is @SpringView I try to navigate to AllPurchasersGUI after click on Button:

allPurchasers = new Button("See all purchasers");
        allPurchasers.addClickListener(e -> //getUI().getPage().setLocation("allpurchasers")
                getUI().getNavigator().navigateTo("allpurchasers")
        );

And here is big problem because in AllPurchasersGUI is:

@Autowired
private final OrderRepository orderRepository;

when I have constructor with parameters:

public AllPurchasersGUI(OrderRepository or) {
        System.out.println("allpurchasers");
        this.orderRepository = or;
        this.grid = new Grid<>(Order.class);
        grid.setSizeFull();
    }

it's oke but Vaadin force me to add constructor without parameters but then I would need to initialize orderRepository so I get an error:

Error:(26, 5) java: variable orderRepository might not have been initialized

Is there any option to avoid default constructor? Or is there other solution?

@Edit AllPurchasersGUI class:

package purchasers;

import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.ui.*;
import order.Order;
import order.OrderRepository;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@SpringView(name="allpurchasers")
public class AllPurchasersGUI extends VerticalLayout implements View {

    /*@Autowired
    private final OrderRepository orderRepository;*/

    final Grid<Order> grid;

    public AllPurchasersGUI()
    {
        System.out.println("allpurchasers");
        this.grid = new Grid<>(Order.class);
        grid.setSizeFull();
    }

    public AllPurchasersGUI(OrderRepository or) {
        System.out.println("allpurchasers");
        //this.orderRepository = or;
        this.grid = new Grid<>(Order.class);
        grid.setSizeFull();
    }

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event)
    {
        Notification.show("Im in all purchasers");
        listPurchasers();
    }

    /**
     * method to display orders in grid
     */
    private void listPurchasers()
    {
        //List<Order> allOrders = (List<Order>) orderRepository.findAll();
        Order order = new Order("mwalko", 123L, "klapa", LocalDate.now());
        List<Order> allOrders = new ArrayList<Order>();
        allOrders.add(order);
        grid.setItems(allOrders);
        grid.setColumns("id", "login", "dateOfOrder");
        addComponent(grid);
    }
}

and the error when I remove constructor without parameters:

java.lang.IllegalArgumentException: Unable to create an instance of {0}. Make sure the class has a public no-arg constructor.
Michu93
  • 5,058
  • 7
  • 47
  • 80
  • If you want Spring, go all the way, with Spring views & Navigator as well. The "classic" navigator requires a no-arg constructor so it can instantiate your views, but it will also not inject your Spring dependencies, aka your `OrderRepository`. For this to work correctly, everything has to be "spring managed". Take a look at [the docs](http://vaadin.github.io/spring-tutorial/#_spring_views) for tutorial/samples. – Morfic Apr 23 '18 at 11:01
  • @Morfic Do you recomend SpringNavigator instead of vaadin's one? Is it really impossible to avoid non-arg constructor? I like to create GUI in Vaadin but has so many problems with it's sheath. – Michu93 Apr 23 '18 at 14:12
  • They are both "Vaadin's". The difference is how they "obtain" the view instances. While you can probably do the same with the basic [`Navigator`](https://vaadin.com/api/com/vaadin/navigator/Navigator.html), the [`SpringNavigator`](https://vaadin.com/api/vaadin-spring/com/vaadin/spring/navigator/SpringNavigator.html) automatically uses a [`SpringView`](https://vaadin.com/api/vaadin-spring/com/vaadin/spring/navigator/SpringViewProvider.html) to retrieve view instances from the Spring container, making your life easier. – Morfic Apr 23 '18 at 14:21
  • And no, there's no need for the no-arg view constructors. The view instances are retrieved from the Spring context, so the objects are actually created by Spring, and all their dependencies injected. **Note** [please be aware that the annotation order on the view is important](https://stackoverflow.com/questions/44903429/uiscope-annotation-not-respected-for-spring-view/44907781#44907781)! – Morfic Apr 23 '18 at 14:26

2 Answers2

1

If you are forced to use no-arg constructor, then you can use it and inject OrderRepository by field using @Autowired annotation. But until your field is declare as final, you can't do this. I would prefer inject dependecies by constructor but maybe in this case, you can use field injection.

mdolata
  • 184
  • 12
0

Could you post the complete AllPurchasersGUI class. And whats the error that says you should have an empty Constructor. I imagine your class to extend some kind of generated VaadinView, then you should not have a problem with your constructor

Edit: Ok i tryed to make a class thats like yours and i do not have the exception. Could it be that you cant create your Repository and that Unable to create an instance of {0} references to the 0 param in your AllPurchasersGUI constructor? Other then that im afraid i cannot help you :/

Marcus Lanvers
  • 383
  • 5
  • 20
  • But earlier I used this class as UI instead of view and @Autowired worked perfectly. I think orderRepository somehow have to be initialized in constructor but got no idea how. – Michu93 Apr 23 '18 at 09:54
  • orderRepository should be a Interface from which a Class will be generated when autowireing so thats why youll need to have some kind of autowire in your class. I have no idea why it gives you that exception. I autowire a RepositoryInterface in my class aswell and i do not get that exception – Marcus Lanvers Apr 23 '18 at 09:59
  • Yes, of course it's an interface but I think vaadin's navigator call constructor with no parameters. – Michu93 Apr 23 '18 at 10:07