Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

Vaadin Spring + MVP + Hibernate ... How?

Shindo Kataoka
6 years ago Oct 06, 2015 4:13pm

Hello community!
I'm setting up my first Vaadin application with Vaadin 7.5.6 and the official Vaadin Spring 1.0.0.
My vision is to have the following technologies included:

  • MVP Structure

    [*]Vaadin Spring 1.0.0

    • Dependency injection
    • Scopes
    • SpringUI provider, SpringView provider + Navigator support

  • Spring ORM
    • SessionFactory SpringBean creation (org.springframework.orm.hibernate4.LocalSessionFactoryBean)
    • TransactionManager SpringBean creation (for @Transactional annotation: org.springframework.orm.hibernate4.HibernateTransactionManager)

  • Hibernate ORM
    • DTO Mapping
    • Database operations

  • Responsive Menu Layout (from official demo)

Because I'm new to Vaadin & MVP I was a bit confused when I saw the unofficial MVP Addon from vaadin4spring. It uses an Eventbus, which is new to me, and I'm asking myself if that's the recommended way. Anyway, I started trying to build a MVP structure in the use of Vaadin Spring 1.0.0.
My current code looks like this:

UI class:

@Theme("mytheme")
@SpringUI
@EnableVaadin
public class MyUI extends UI
{
    private static final long serialVersionUID = -5508691235080555823L;

    @Autowired
    SpringViewProvider viewProvider;

    @Autowired
    MainViewPresenter mainViewPresenter;

    @Autowired
    ApplicationContext applicationContext;

    @Override
    protected void init(VaadinRequest vaadinRequest)
    {
        setLocale(Locale.GERMANY);
        Page.getCurrent().setTitle("MyApp");
        Responsive.makeResponsive(this);

        updateContent();
    }

    private void initNavigator(ComponentContainer content)
    {
        setNavigator(null);

        Navigator navigator = new Navigator(this, content);
        navigator.addProvider(viewProvider);
        navigator.setErrorView(applicationContext.getBean(ErrorViewPresenter.class).getView());

        setNavigator(navigator);
    }

    private void updateContent()
    {
        boolean userIsLoggedIn = VaadinSession.getCurrent().getAttribute("user") != null;

        if (userIsLoggedIn)
        {
            redirectToMainView();
        } else
        {
            // Cookie handling...

            Cookie myCookie = [...]

            if (myCookie != null)
            {
                [... getting user from cookie ...]

                VaadinSession.getCurrent().setAttribute("user", user);

                redirectToMainView();
            } else
            {
                setContent(applicationContext.getBean(LoginViewPresenter.class).getView());
              
                addStyleName("loginview");
            }
        }
    }

    private void redirectToMainView()
    {
        initNavigator(mainViewPresenter.getView().getContent());
        addStyleName(ValoTheme.UI_WITH_MENU);
        mainViewPresenter.getView().setMenu(applicationContext.getBean(MenuViewPresenter.class).getView());

        setContent(mainViewPresenter.getView());
        removeStyleName("loginview");
    

MainView:

@SuppressWarnings("serial")
@UIScope
@SpringView(name = MainView.NAME)
public class MainView extends HorizontalLayout implements View
{
    public static final String NAME = "MainView";

    private CssLayout menu = new CssLayout();
    private CssLayout content = new CssLayout();

    @PostConstruct
    private void init()
    {
        setSizeFull();
        addStyleName("mainview");

        // Menü
        menu.setPrimaryStyleName(ValoTheme.MENU_ROOT);
        menu.addStyleName("v-scrollable");
        addComponent(menu);

        // Content
        content.addStyleName("view-content");
        content.setSizeFull();
        addComponent(content);

        setExpandRatio(content, 1.0f);
    }

    @Override
    public void enter(ViewChangeEvent event)
    {

    }

    public CssLayout getContent()
    {
        return content;
    }

    public void setMenu(Component menu)
    {
        this.menu.removeAllComponents();
        this.menu.addComponent(menu);
    }

MainViewPresenter:

@UIScope
@SpringComponent
public class MainViewPresenter implements Serializable
{
    private static final long serialVersionUID = -898180058329832335L;

    @Autowired
    private MainView view;

    @PostConstruct
    public void init()
    {

    }

    public MainView getView()
    {
        return view;
    }

}

HomeView:

@SuppressWarnings("serial")
@UIScope
@SpringView(name = HomeView.NAME)
public class HomeView extends Panel implements View
{
    public static final String NAME = "";

    private VerticalLayout root;

    @PostConstruct
    private void init()
    {
        addStyleName(ValoTheme.PANEL_BORDERLESS);
        setSizeFull();
        root = new VerticalLayout();
        root.setSizeFull();
        root.setMargin(true);
        root.addStyleName("dashboard-view");
        setContent(root);
        Responsive.makeResponsive(root);

        root.addComponent(buildHeader());

        Component content = buildContent();
        root.addComponent(content);
        root.setExpandRatio(content, 1);
    }

    private Component buildHeader()
    {
        HorizontalLayout header = new HorizontalLayout();
        header.addStyleName("viewheader");
        header.setSpacing(true);

        Label titleLabel = new Label("Startseite");
        titleLabel.setSizeUndefined();
        titleLabel.addStyleName(ValoTheme.LABEL_H1);
        titleLabel.addStyleName(ValoTheme.LABEL_NO_MARGIN);

        header.addComponent(titleLabel);

        return header;
    }

    private Component buildContent()
    {
        HorizontalLayout layout = new HorizontalLayout();
        layout.addStyleName("dashboard-panels");

        Label label = new Label("Welcome!!!");
        layout.addComponent(label);

        return layout;
    }

    @Override
    public void enter(ViewChangeEvent event)
    {

    }
}

HomeViewPresenter:

@SpringComponent
@UIScope
public class HomeViewPresenter implements Serializable
{
    private static final long serialVersionUID = 1504172856408784656L;

    @Autowired
    private HomeView view;

    @PostConstruct
    public void init()
    {

    }

    public HomeView getView()
    {
        return view;
    }

    public void setView(HomeView view)
    {
        this.view = view;
    }
}

My pom.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    [...]

    <repositories>
        <repository>
            <id>vaadin-addons</id>
            <url>http://maven.vaadin.com/vaadin-addons</url>
        </repository>
        <repository>
            <id>vaadin-snapshots</id>
            <url>https://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
       
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-server</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-push</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-themes</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-client-compiled</artifactId>
        </dependency>
       

        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring</artifactId>
            <version>1.0.0</version>
        </dependency>
       
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>
       
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.11.Final</version>
        </dependency>
       
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <encoding>${project.encoding}</encoding>
                    <source>${project.source.version}</source>
                    <target>${project.target.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <encoding>${project.encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <!-- Exclude some unnecessary files generated by the GWT compiler. -->
                    <packagingExcludes>WEB-INF/classes/VAADIN/gwt-unitCache/**,    WEB-INF/classes/VAADIN/widgetsets/WEB-INF/**</packagingExcludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.plugin.version}</version>
                <configuration>
                    <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>
                    <webappDirectory>${basedir}/target/classes/VAADIN/widgetsets</webappDirectory>
                    <draftCompile>false</draftCompile>
                    <compileReport>false</compileReport>
                    <style>OBF</style>
                    <strict>true</strict>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>clean</goal> <!-- deleteMeIfItsNotWorking -->
                            <goal>resources</goal> <!-- deleteMeIfItsNotWorking -->
                            <goal>update-theme</goal>
                            <goal>update-widgetset</goal>
                            <goal>compile-theme</goal> <!-- deleteMeIfItsNotWorking -->
                            <goal>compile</goal>
                            <!-- disabled by default to use on-the-fly theme compilation -->
                            <!-- <goal>compile-theme</goal> -->
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.4</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.6.1</version>
                <!-- Clean up also any pre-compiled themes -->
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>src/main/webapp/VAADIN/themes</directory>
                            <includes>
                                <include>**/styles.css</include>
                                <include>**/styles.scss.cache</include>
                            </includes>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>

            <!-- The Jetty plugin allows us to easily test the development build by
                running jetty:run on the command line. -->
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>${jetty.plugin.version}</version>
                <configuration>
                    <scanIntervalSeconds>2</scanIntervalSeconds>
                </configuration>
            </plugin>
        </plugins>

        <pluginManagement>
            <plugins>
                <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
                <!-- TODO Remove when http://dev.vaadin.com/ticket/14924 is resolved -->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>com.vaadin</groupId>
                                        <artifactId>
                                            vaadin-maven-plugin
                                        </artifactId>
                                        <versionRange>[7.1.11,)</versionRange>
                                        <goals>
                                            <goal>resources</goal>
                                            <goal>update-widgetset</goal>
                                            <goal>compile</goal>
                                            <goal>compile-theme</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>

    </build>

</project>

My applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation=
    "http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd"
    xmlns:tx="http://www.springframework.org/schema/tx">
    <context:component-scan base-package="de.myApp" />
 
<!--     <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> -->
<!--         <property name="configLocation"    value="classpath:de/myApp/hibernate/dto/hibernate.cfg.xml" /> -->
<!--     </bean> -->
  
<!--     <tx:annotation-driven transaction-manager="transactionManager" /> -->
<!--     <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> -->
<!--         <property name="sessionFactory" ref="sessionFactory" /> -->
<!--     </bean> -->
 
</bean

My questions:

1. As you can see I'm injecting the view in the particular presenter. Is this the right way? Or do you advise to use the unofficial MVP Addon?

    1.1. Does the View know the presenter? I heard a lot of variants about MVP...

2. How can I save the state of a presenter? If I'm fetching a lot of data from a database in a presenter I want to save it although the user refreshes the page. Is it the @PreserveOnRefresh annotation over the UI class?

3. Did i forgot any dependencies for my plan?

Best regards
shinchillahh2000

Abhijeet Tayade
6 years ago Nov 02, 2015 11:50am
Shindo Kataoka
6 years ago Nov 02, 2015 1:18pm