Vaadin-Grid не отображает данные из базы данных, которую он должен показывать
Я пишу приложение Vaadin Spring, и у меня проблема с тем, что данные из базы данных не отображаются в таблице (= компонент пользовательского интерфейса Vaadin 8 для отображения таблиц).
У меня есть подозрение относительно того, где может быть ошибка (см. Мои замечания в конце этого поста).
Все остальное (кроме данных, не отображаемых в таблице) работает нормально. Таблица базы данных была автоматически создана с помощью аннотаций Spring JPA, Grid хорошо отображается в пользовательском интерфейсе и т. Д.... только данные из базы данных не отображаются в Grid.
Для этого вопроса я создал новый мини-проект. Код для этого мини-проекта вы можете найти ниже. Пользовательский интерфейс просто состоит из таблицы, которая должна отображать содержимое базы данных. (Поскольку Grid ничего не отображает, пользовательский интерфейс в основном пустой кадр, см. Последний скриншот).
Проблема в этом мини-проекте такая же, как и в оригинальном (и гораздо более крупном) проекте: данные из базы данных не отображаются в Grid.
Мини-проект называется "демо" и был создан с помощью SpringInitializr. Выбранные зависимости показаны на следующем снимке экрана:
Мое демо-приложение состоит из 3 маленьких пакетов: model, database_access и ui:
Модель состоит из одного класса под названием "Человек". Вот код этого файла:
package com.example.demo.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="Persons")
public class Person {
@Id
@Column(name="id")
private int id;
@Column(name="name")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Пакет доступа к базе данных состоит из 3 файлов:
PersonRepository, PersonService и PersonServiceImpl
... где PersonServiceImpl является реализацией интерфейса PersonService.
Вот PersonRepository:
package com.example.demo.database_acess;
import com.example.demo.model.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.stream.Stream;
@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
@Query("SELECT p FROM Person p")
Stream<Person> findAllByCustomQueryAndStream();
}
Вот PersonService:
package com.example.demo.database_acess;
import com.example.demo.model.Person;
import java.util.stream.Stream;
public interface PersonService {
Stream<Person> streamAllPersons();
long countPersons();
}
а вот PersonServiceImpl:
package com.example.demo.database_acess;
import com.example.demo.model.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.stream.Stream;
@Service
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonRepository personRepository;
@Transactional
public Stream<Person> streamAllPersons() {
return personRepository.findAllByCustomQueryAndStream();
}
public long countPersons() {
return personRepository.count();
}
}
Пакет пользовательского интерфейса состоит из следующих четырех файлов: GUI, PersonsView, PersonsGrid и PersonDataProvider
GUI:
package com.example.demo.ui;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Title;
import com.vaadin.navigator.Navigator;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.spring.navigator.SpringViewProvider;
import com.vaadin.ui.Panel;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import org.springframework.beans.factory.annotation.Autowired;
@SpringUI
@Title("Demo App")
@Theme("valo")
public class GUI extends UI {
@Autowired
private SpringViewProvider viewProvider;
@Override
protected void init(VaadinRequest request) {
VerticalLayout rootLayout = new VerticalLayout();
rootLayout.setSizeFull();
setContent(rootLayout);
Panel viewContainer = new Panel();
viewContainer.setSizeFull();
rootLayout.addComponent(viewContainer);
rootLayout.setExpandRatio(viewContainer, 1.0f);
Navigator navigator = new Navigator(this, viewContainer);
navigator.addProvider(viewProvider);
}
}
PersonsView:
package com.example.demo.ui;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.VerticalLayout;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
@UIScope
@SpringView(name= PersonsView.NAME)
public class PersonsView extends VerticalLayout implements View {
public static final String NAME = "";
@Autowired
private PersonsGrid personsGrid;
@PostConstruct
void init() {
setMargin(false);
addComponent(personsGrid);
personsGrid.setSizeFull();
}
@Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
}
}
PersonsGrid:
package com.example.demo.ui;
import com.example.demo.model.Person;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.ui.Grid;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
@SpringComponent
public class PersonsGrid extends Grid<Person> {
@Autowired
private PersonDataProvider personDataProvider;
@PostConstruct
void init() {
setDataProvider(personDataProvider);
}
}
PersonDataProvider:
package com.example.demo.ui;
import com.example.demo.database_acess.PersonServiceImpl;
import com.example.demo.model.Person;
import com.vaadin.data.provider.AbstractBackEndDataProvider;
import com.vaadin.data.provider.Query;
import com.vaadin.spring.annotation.SpringComponent;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.stream.Stream;
@SpringComponent
public class PersonDataProvider extends AbstractBackEndDataProvider<Person, Void> {
@Autowired
PersonServiceImpl personService;
public Stream<Person> fetchFromBackEnd(Query<Person, Void> query) {
return personService.streamAllPersons();
}
public int sizeInBackEnd(Query<Person, Void> query) {
return (int) personService.countPersons();
}
}
Файл application.properties выглядит следующим образом:
spring.datasource.url=jdbc:mysql://localhost:3306/demoDB
spring.datasource.username=root
spring.datasource.password=mypassword
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=create
Я вставил двух человек в базу данных (Билл и Джордж):
Однако эти лица не отображаются в сетке, как вы можете видеть на следующем снимке экрана:
При написании кода для Grid (PersonGrid) и DataProvider (PersonDataProvider) я следовал примерам из Интернета (например, http://vaadinhelp.co.in/vaadin-dataprovider-example/).
... Я подозреваю, что в одном из этих двух файлов (т.е. PersonGrid и PersonDataProvider) что-то отсутствует или неправильно.
Однако я не знаю что.
************************************ОБНОВИТЬ************* ***************************
Я добавил следующие две строки в init-функцию PersonsView-Class:
personsGrid.addColumn(Person::getName).setCaption("Name");
personsGrid.addColumn(Person::getId).setCaption("ID");
После перезапуска приложения в сетке появилось 3 строки (одна для заголовка, одна для "Джорджа" и одна для "Билла").
Но: строки отображаются неправильно, как вы можете видеть на следующем скриншоте:
В верхнем левом углу вы видите начало трех строк, но столбцы не отображаются.
Что мне нужно сделать, чтобы данные отображались правильно?
******************************* UPDATE2 ****************** ************************
Видимо, некоторые SQL-операции запрещены после закрытия ResultSet (см. Скриншот ниже). Я не знаю, что это значит, хотя.