Sample-vaadin-spring-hibernate » History » Version 19
Henning Blohm, 07.09.2021 19:14
1 | 1 | Henning Blohm | h1. A sample using Vaadin with Hibernate JPA and Spring on Z2 |
---|---|---|---|
2 | |||
3 | This sample is similar to [[Sample-spring-hibernate]] but differs (or rather extends) in that it show cases |
||
4 | the use of the "Vaadin":http://www.vaadin.com user interface toolkit in conjunction with Spring implemented annotation based |
||
5 | dependency injection over Z2 modularity. |
||
6 | |||
7 | As Spring is used throughout - in all modules - this is another practical application of [[How to Spring]]. |
||
8 | |||
9 | 8 | Henning Blohm | Moreover this sample illustrates modularization of Vaadin user interfaces with Z2 using extension points as described in [[Vaadin add-on]]. |
10 | |||
11 | 1 | Henning Blohm | This sample is stored in "z2-samples.vaadin-spring-hibernate":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate. |
12 | |||
13 | 19 | Henning Blohm | *NOTE:* This sample has been discontinued as of v2.9. |
14 | |||
15 | 1 | Henning Blohm | h2. Prerequisites |
16 | |||
17 | 13 | Henning Blohm | {{include(Java Version Requirements)}} |
18 | 12 | Henning Blohm | |
19 | 1 | Henning Blohm | You need to run Java DB as network server on localhost. This is explained next. |
20 | |||
21 | The application will create a database "z2-samples" |
||
22 | |||
23 | {{include(How to run Java db)}} |
||
24 | |||
25 | |||
26 | h2. Run it |
||
27 | |||
28 | If you have the database, the fastest way to verify whether it runs is: |
||
29 | |||
30 | 19 | Henning Blohm | <pre><code class="ruby"> |
31 | mkdir install |
||
32 | cd install |
||
33 | </code></pre> |
||
34 | |||
35 | {{include(Install z2-base-v28)}} |
||
36 | 1 | Henning Blohm | |
37 | 15 | Henning Blohm | Check out the sample |
38 | 1 | Henning Blohm | |
39 | 17 | Henning Blohm | <pre><code class="bash"> |
40 | 18 | Henning Blohm | git clone -b v2.8 https://www.z2-environment.net/git/z2-samples.vaadin-spring-hibernate |
41 | 1 | Henning Blohm | </code></pre> |
42 | 15 | Henning Blohm | |
43 | {{include(Install_sample_postfix)}} |
||
44 | 1 | Henning Blohm | |
45 | When running, go to http://localhost:8080/vaadin-spring-hibernate. You should see this: |
||
46 | |||
47 | !vaadin-spring-hibernate.png! |
||
48 | |||
49 | h2. Details |
||
50 | |||
51 | 3 | Henning Blohm | As in the other samples we have a re-use domain module. That is a recurring theme for many good reasons. In this case, the domain module "com.zfabrik.samples.vaadin-spring-hibernate.domain":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/show/com.zfabrik.samples.vaadin-spring-hibernate.domain is essentially like the similarly named module of [[Sample-spring-hibernate]]. The only difference is some more data access methods in the "ThingyRepository":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/entry/com.zfabrik.samples.vaadin-spring-hibernate.domain/java/src.api/com/zfabrik/samples/vaadin_spring_hibernate/thingies/ThingyRepository.java. |
52 | 1 | Henning Blohm | |
53 | 3 | Henning Blohm | The Vaadin Web application is defined in the module "com.zfabrik.samples.vaadin-spring-hibernate.web":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/show/com.zfabrik.samples.vaadin-spring-hibernate.web. It has the usual Spring application context in "web/WebContent/WEB-INF/applicationContext.xml":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/entry/com.zfabrik.samples.vaadin-spring-hibernate.web/web/WebContent/WEB-INF/applicationContext.xml that imports the thingy repository: |
54 | 1 | Henning Blohm | |
55 | 3 | Henning Blohm | <pre><code class="xml"> |
56 | <!-- import external components --> |
||
57 | <bean id="thingyRepository" class="com.zfabrik.springframework.ComponentFactoryBean"> |
||
58 | <property name="componentName" value="com.zfabrik.samples.vaadin-spring-hibernate.domain/repository" /> |
||
59 | <property name="className" value="com.zfabrik.samples.vaadin_spring_hibernate.thingies.ThingyRepository" /> |
||
60 | </bean> |
||
61 | </code></pre> |
||
62 | |||
63 | 5 | Henning Blohm | One particularity of using Vaadin in a modular environment is that Vaadin loads it's application class using the class loader that loaded the Vaadin classes (rather than the current thread's context class loader - as would be advised normally). When the Web application module is separated from the Vaadin module this can obviously not work too well (see also "Enhancement #9809":http://dev.vaadin.com/ticket/9809). To fix that you can tell Vaadin to use a custom class loader implementation (that - again - is loaded with the Vaadin class loader). That's why we declare the Vaadin servlet in "web/WebContent/WEB-INF/web.xml":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/entry/com.zfabrik.samples.vaadin-spring-hibernate.web/web/WebContent/WEB-INF/web.xml list this: |
64 | |||
65 | <pre><code class="xml"> |
||
66 | <!-- Vaadin --> |
||
67 | <servlet> |
||
68 | <servlet-name>VaadinServlet</servlet-name> |
||
69 | <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class> |
||
70 | <init-param> |
||
71 | <param-name>application</param-name> |
||
72 | <param-value>com.zfabrik.samples.impl.vaadin_spring_hibernate.ApplicationImpl</param-value> |
||
73 | </init-param> |
||
74 | 1 | Henning Blohm | <!-- this because Vaadin doesn't use the thread's context class loader by default --> |
75 | 8 | Henning Blohm | <init-param> |
76 | 5 | Henning Blohm | <param-name>ClassLoader</param-name> |
77 | <param-value>com.zfabrik.vaadin.ContextClassLoader</param-value> |
||
78 | </init-param>* |
||
79 | </servlet> |
||
80 | </code></pre> |
||
81 | |||
82 | 3 | Henning Blohm | The Vaadin application class "ApplicationImpl":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/entry/com.zfabrik.samples.vaadin-spring-hibernate.web/java/src.impl/com/zfabrik/samples/impl/vaadin_spring_hibernate/ApplicationImpl.java constructs a simple view hierarchy that containes a table view based on a "lazy query container add-on":https://vaadin.com/directory#addon/lazy-query-container data model that is fed from the domain module. To do so the corresponding query implementation (in lazy query container speak) has the repository injected: |
83 | |||
84 | <pre><code class="java"> |
||
85 | @Configurable |
||
86 | public class ThingiesQuery implements Query { |
||
87 | @Autowired |
||
88 | private ThingyRepository repository; |
||
89 | private Integer size; |
||
90 | private boolean asc; |
||
91 | |||
92 | // ... |
||
93 | } |
||
94 | </code></pre> |
||
95 | 5 | Henning Blohm | |
96 | Please browse the actual UI code at "com.zfabrik.samples.vaadin-spring-hibernate.web/java/src.impl/com/zfabrik/samples/impl/vaadin_spring_hibernate":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/show/com.zfabrik.samples.vaadin-spring-hibernate.web/java/src.impl/com/zfabrik/samples/impl/vaadin_spring_hibernate. It pretty much speaks for itself. |
||
97 | 4 | Henning Blohm | |
98 | 10 | Henning Blohm | h3. Transaction Management |
99 | |||
100 | 4 | Henning Blohm | One important note on transaction management: In this example, transaction boundaries are enforced by a servlet filter once more. It is implemented in "TransactionFilter":http://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/entry/com.zfabrik.samples.vaadin-spring-hibernate.web/java/src.impl/com/zfabrik/samples/impl/vaadin_spring_hibernate/util/TransactionFilter.java and essentially looks like this: |
101 | |||
102 | <pre><code class="java"> |
||
103 | public class TransactionFilter implements Filter { |
||
104 | |||
105 | |||
106 | @Transactional |
||
107 | @Override |
||
108 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
||
109 | chain.doFilter(request, response); |
||
110 | } |
||
111 | |||
112 | } |
||
113 | </code></pre> |
||
114 | |||
115 | In other words, the only thing it really does is to make sure Spring spans a transaction (using the underlying JTA implementation) along the request. It is tempting to implement transaction demarcation in the Vaadin Application class. However, we cannot use the <code>@Transactional</code> annotation as there is no single request spanning method and using the JTA UserTransaction object is unfortunately not sufficient to "remote control" Spring's JTA wrappers. So the easiest work around is to use Spring TX demarcation right away (see also [[how to transaction management]]). |
||
116 | 10 | Henning Blohm | |
117 | h3. Extensibility |
||
118 | 6 | Henning Blohm | |
119 | 7 | Henning Blohm | Furthermore this sample illustrates the use of the *ExtensionComponentsUtil* ("javadoc":http://www.z2-environment.net/javadoc/com.zfabrik.vaadin!2Fjava/api/com/zfabrik/vaadin/ExtensionComponentsUtil.html) as described in detail at [[Vaadin_Add-on]]. This utility allows to conveniently modularize the user interface implementation by providing and retrieving Vaadin user interface component implementations across modules. |
120 | 6 | Henning Blohm | |
121 | 11 | Henning Blohm | In the specific case, the module "com.zfabrik.samples.vaadin-spring-hibernate.extension":https://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/show/com.zfabrik.samples.vaadin-spring-hibernate.extension provides an extension component "somethingAboutThingies":https://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/entry/com.zfabrik.samples.vaadin-spring-hibernate.extension/somethingAboutThingies.properties that is added as the button "About these..." to the button toolbar of the main interface. |
122 | |||
123 | The component declaration makes sure the implementation can be found and (important!) that the module's Spring application context is loaded before providing the component implementation |
||
124 | |||
125 | <pre><code class="bash"> |
||
126 | # |
||
127 | # A Vaadin UI extension |
||
128 | # |
||
129 | com.zfabrik.component.type=com.vaadin.ui.Component |
||
130 | |||
131 | # |
||
132 | # Coordinates: |
||
133 | # |
||
134 | com.zfabrik.vaadin.extension.point=com.zfabrik.samples.vaadin_spring_hibernate.actions |
||
135 | com.zfabrik.vaadin.extension.order=100 |
||
136 | |||
137 | # |
||
138 | # The implementation class |
||
139 | # |
||
140 | component.className=com.zfabrik.samples.impl.vaadin_spring_hibernate.ext.SomethingAboutThingies |
||
141 | |||
142 | # |
||
143 | # make sure the app context is loaded first |
||
144 | # |
||
145 | com.zfabrik.component.dependencies=\ |
||
146 | com.zfabrik.samples.vaadin-spring-hibernate.extension/applicationContext |
||
147 | </code></pre> |
||
148 | |||
149 | The user interface that assembles consumes this extension is at "ThingiesView":https://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/entry/com.zfabrik.samples.vaadin-spring-hibernate.web/java/src.impl/com/zfabrik/samples/impl/vaadin_spring_hibernate/ThingiesView.java and adds extensions like this: |
||
150 | |||
151 | <pre><code class="java"> |
||
152 | // find extensions and add them to the button row |
||
153 | for (Component c : ExtensionComponentsUtil.getComponentyByExtensionForApplication(application,"com.zfabrik.samples.vaadin_spring_hibernate.actions")) { |
||
154 | // and add them to this. |
||
155 | buttons.addComponent(c); |
||
156 | } |
||
157 | </code></pre> |