Monday, 28 January 2013

ZK With Spring + JPA + Hibernate Entity Manager

In this article, let us see how we can integrate ZK With spring, JPA and Hibernate Entity Manager.

Technologies Used

    1. ZK 6.5 CE Version
    2. Hibernate Entity Manager Version 4.1.9 Final.
    3. Hibernate Core Version 4.1.9 Final
    4. Spring ORM Version 3.2.0
    5. MySQL version 5

Reference

Project Name and Structure

ZKSpringJPA

image

Step 1:

If you are new ZK, then you can setup the Development environment by downloading this document.

Step 2:

MySQL Setup. Let us create the following table in MySQL. Let us create the following table and insert two records by default.
CREATE TABLE `zkspringjpaexample` 
    (
          `ID` bigint(20) NOT NULL auto_increment,
          `FirstName` varchar(100) default NULL,
            `LastName` varchar(100) default NULL,
            `LoginName` varchar(100) default NULL,
          PRIMARY KEY  (`ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1


Step 3:

Now let us create ZK Maven Project. By default POM File will point ZK 6.0.1 Version. we will change this to latest version 6.5.0 and also we will include all the dependency. You can copy the below POM.xml
<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>
    <groupId>ZKSpringJPA</groupId>
    <artifactId>ZKSpringJPA</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <zk.version>6.5.0</zk.version>
        <commons-io>1.3.1</commons-io>
        <maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>
        <packname>-${project.version}-FL-${maven.build.timestamp}</packname>
        <jsr330.version>1</jsr330.version>
        <spring-data-jpa.version>1.0.3.RELEASE</spring-data-jpa.version>
        <servlet-api.version>2.4</servlet-api.version>
        <slf4j.version>1.6.1</slf4j.version>
    </properties>
    <packaging>war</packaging>
    <name>The ZKExamples Project</name>
    <description>The ZKExamples Project</description>
    <licenses>
        <license>
            <name>GNU LESSER GENERAL PUBLIC LICENSE, Version 3</name>
            <url>http://www.gnu.org/licenses/lgpl.html</url>
            <distribution>repo</distribution>
        </license>
    </licenses>
    <repositories>
        <repository>
            <id>ZK CE</id>
            <name>ZK CE Repository</name>
            <url>http://mavensync.zkoss.org/maven2</url>
        </repository>
        <repository>
            <id>ZK EVAL</id>
            <name>ZK Evaluation Repository</name>
            <url>http://mavensync.zkoss.org/eval</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>zkmaven</id>
            <name>ZK Maven Plugin Repository</name>
            <url>http://mavensync.zkoss.org/maven2/</url>
        </pluginRepository>
    </pluginRepositories>
    <dependencies>
        <dependency>
            <groupId>org.zkoss.zk</groupId>
            <artifactId>zkbind</artifactId>
            <version>${zk.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>${slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.zkoss.zk</groupId>
            <artifactId>zul</artifactId>
            <version>${zk.version}</version>
        </dependency>
        <dependency>
            <groupId>org.zkoss.zk</groupId>
            <artifactId>zkplus</artifactId>
            <version>${zk.version}</version>
        </dependency>
        <dependency>
            <groupId>org.zkoss.zk</groupId>
            <artifactId>zhtml</artifactId>
            <version>${zk.version}</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons-io}</version>
        </dependency>

        <!-- ZK 5 breeze theme <dependency> <groupId>org.zkoss.theme</groupId> 
            <artifactId>breeze</artifactId> <version>${zk.version}</version> <optional>true</optional> 
            </dependency> -->
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.1.9.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.1.9.Final</version>
        </dependency>


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.22</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data-jpa.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

    </dependencies>
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <!-- Run with Jetty -->
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.10</version>
                <configuration>
                    <scanIntervalSeconds>5</scanIntervalSeconds>
                    <stopKey>foo</stopKey>
                    <stopPort>9999</stopPort>
                </configuration>
                <executions>
                    <execution>
                        <id>start-jetty</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <scanIntervalSeconds>0</scanIntervalSeconds>
                            <daemon>true</daemon>
                        </configuration>
                    </execution>
                    <execution>
                        <id>stop-jetty</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!-- Compile java -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <!-- Build war -->
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <groupId>org.apache.maven.plugins</groupId>
                <version>2.1.1</version>
            </plugin>
            <!-- Pack zips -->
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2</version>
                <executions>
                    <execution>
                        <id>webapp</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <finalName>ZKSpringJPA${packname}</finalName>
                            <appendAssemblyId>false</appendAssemblyId>
                            <descriptors>
                                <descriptor>assembly/webapp.xml</descriptor>
                            </descriptors>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>


Step 4:

Now let us create our domain object as follows
package zkMVVM.zKMVVMSpringJPA;


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "zkspringjpaexample")
public class ZkSpringJpaExample {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "firstName")
    private String firstName;

    @Column(name = "LastName")
    private String lastName;
    
    @Column(name = "loginName")
    private String loginName;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }
    
    
}


Step 5:

Now let us create Service and DAO Layers as follows.
ZkSpringJpaExampleService.java
package zkMVVM.zKMVVMSpringJPA;

import java.util.List;

public interface ZkSpringJpaExampleService {
    public List<ZkSpringJpaExample> findAll();
}

ZkSpringJpaExampleServiceImpl.java

package zkMVVM.zKMVVMSpringJPA;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

public class ZkSpringJpaExampleServiceImpl implements ZkSpringJpaExampleService {

    private ZkSpringJpaExampleDao ZkSpringJpaExampleDao;

    @Transactional(readOnly=true)
    public List<ZkSpringJpaExample> findAll() {
        return ZkSpringJpaExampleDao.findAll();
    }

    public ZkSpringJpaExampleDao getZkSpringJpaExampleDao() {
        return ZkSpringJpaExampleDao;
    }

    public void setZkSpringJpaExampleDao(ZkSpringJpaExampleDao zkSpringJpaExampleDao) {
        ZkSpringJpaExampleDao = zkSpringJpaExampleDao;
    }


}



ZkSpringJpaExampleDao.java
package zkMVVM.zKMVVMSpringJPA;

import java.util.List;

public interface ZkSpringJpaExampleDao {
    public List<ZkSpringJpaExample> findAll();

     
}

ZkSpringJpaExampleDaoImpl.java
package zkMVVM.zKMVVMSpringJPA;


import java.util.LinkedList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;


@Repository
public class ZkSpringJpaExampleDaoImpl  implements ZkSpringJpaExampleDao  {

    @PersistenceContext
    private EntityManager em;

 
    @SuppressWarnings("unchecked")
    public List<ZkSpringJpaExample> findAll() {
        List<ZkSpringJpaExample> exList = new LinkedList<ZkSpringJpaExample>();
        Query query = em.createQuery("from ZkSpringJpaExample as ex");
        exList = query.getResultList();
        return exList;
    }
}


Step 6:

Next step to create the ZUL File and its VM File as follows
zkspringjpaexampleListing.zul
<zk>
    <window id="zkspringjpaexampleListing" title="Users List"
        height="90%" border="normal" apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('zkMVVM.zKMVVMSpringJPA.ZKSpringJPAExampleListVM')">
        <separator />
        <listbox id="" mold="paging" pageSize="11" pagingPosition="top"
            selectedItem="@bind(vm.selectedItem)"
            model="@load(vm.examplesListData)">
            <listhead sizable="true">
                <listheader label="First Name" sort="auto(firstName)" />
                <listheader label="Loast Name" sortDirection="ascending"
                    sort="auto(lastName)" />
                <listheader label="Login Name" />
            </listhead>
            <template name="model" var="p1">
                <listitem>
                    <listcell label="@load(p1.firstName)" />
                    <listcell label="@load(p1.lastName)" />
                    <listcell label="@load(p1.loginName)" />
                </listitem>
            </template>
        </listbox>
    </window>
</zk>


ZKSpringJPAExampleListVM.java

package zkMVVM.zKMVVMSpringJPA;

import java.util.List;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.select.Selectors;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.ListModelList;

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class ZKSpringJPAExampleListVM {

    @WireVariable
    private ZkSpringJpaExampleService ZkSpringJpaExampleService;
    private ZkSpringJpaExample selectedItem;
 

    public ZkSpringJpaExample getSelectedItem() {
        return selectedItem;
    }

    public void setSelectedItem(ZkSpringJpaExample selectedItem) {
        this.selectedItem = selectedItem;
    }

    @AfterCompose
    public void initSetup(@ContextParam(ContextType.VIEW) Component view) {
        Selectors.wireComponents(view, this, false);

    }
    
    public List<ZkSpringJpaExample> getexamplesListData() {
        List<ZkSpringJpaExample> result = ZkSpringJpaExampleService.findAll();
        return new ListModelList<ZkSpringJpaExample>(result);
    }

}

Step 7:

Next step to create the persistence.xml file  as follows. Here I have created under the resource folder, so make sure that this folder is added in the build path.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    version="2.0">

    <persistence-unit name="ZKSpringJPA" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.username" value="root" />
            <property name="hibernate.connection.password" value="1234" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/ZKExamples" />
        </properties>
    </persistence-unit>
</persistence>


 


Step 8:

Next step to create the applicationContext.xml in WEB-INF Folder as follows
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/tx
                   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/ZKExamples" />
        <property name="username" value="root" />
        <property name="password" value="1234" />
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="ZKSpringJPA" />
    </bean>


    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>



    <bean id="ZkSpringJpaExampleDao" class="zkMVVM.zKMVVMSpringJPA.ZkSpringJpaExampleDaoImpl" />
    <bean id="ZkSpringJpaExampleService" class="zkMVVM.zKMVVMSpringJPA.ZkSpringJpaExampleServiceImpl">
        <property name="ZkSpringJpaExampleDao" ref="ZkSpringJpaExampleDao" />
    </bean>
    
    <tx:annotation-driven />

    <context:annotation-config />



</beans>


Step 9:

Finally we will refer the applicationContext.xml in the web.xml as follows

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <description><![CDATA[My ZK Application]]></description>
    <display-name>ZKSpringJPA</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
                        /WEB-INF/applicationContext.xml
                </param-value>
    </context-param>
    <!-- Loads the Spring web application context -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Spring filter -->
    <filter>
        <filter-name>OpenEntityManagerInViewFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>OpenEntityManagerInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- //// -->

    <!-- //// -->
    <!-- ZK -->
    <listener>
        <description>ZK listener for session cleanup</description>
        <listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
    </listener>
    <servlet>
        <description>ZK loader for ZUML pages</description>
        <servlet-name>zkLoader</servlet-name>
        <servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>

        <!-- Must. Specifies URI of the update engine (DHtmlUpdateServlet). It 
            must be the same as <url-pattern> for the update engine. -->
        <init-param>
            <param-name>update-uri</param-name>
            <param-value>/zkau</param-value>
        </init-param>
        <!-- Optional. Specifies whether to compress the output of the ZK loader. 
            It speeds up the transmission over slow Internet. However, if you configure 
            a filter to post-processing the output, you might have to disable it. Default: 
            true <init-param> <param-name>compress</param-name> <param-value>true</param-value> 
            </init-param> -->
        <!-- [Optional] Specifies the default log level: OFF, ERROR, WARNING, INFO, 
            DEBUG and FINER. If not specified, the system default is used. <init-param> 
            <param-name>log-level</param-name> <param-value>OFF</param-value> </init-param> -->
        <load-on-startup>1</load-on-startup><!-- Must -->
    </servlet>
    <servlet-mapping>
        <servlet-name>zkLoader</servlet-name>
        <url-pattern>*.zul</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>zkLoader</servlet-name>
        <url-pattern>*.zhtml</url-pattern>
    </servlet-mapping>
    <!-- [Optional] Uncomment it if you want to use richlets. <servlet-mapping> 
        <servlet-name>zkLoader</servlet-name> <url-pattern>/zk/*</url-pattern> </servlet-mapping> -->
    <servlet>
        <description>The asynchronous update engine for ZK</description>
        <servlet-name>auEngine</servlet-name>
        <servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>

        <!-- [Optional] Specifies whether to compress the output of the ZK loader. 
            It speeds up the transmission over slow Internet. However, if your server 
            will do the compression, you might have to disable it. Default: true <init-param> 
            <param-name>compress</param-name> <param-value>true</param-value> </init-param> -->
        <!-- [Optional] Specifies the AU extension for particular prefix. <init-param> 
            <param-name>extension0</param-name> <param-value>/upload=com.my.MyUploader</param-value> 
            </init-param> -->
    </servlet>
    <servlet-mapping>
        <servlet-name>auEngine</servlet-name>
        <url-pattern>/zkau/*</url-pattern>
    </servlet-mapping>

    <!-- [Optional] Uncomment if you want to use the ZK filter to post process 
        the HTML output generated by other technology, such as JSP and velocity. 
        <filter> <filter-name>zkFilter</filter-name> <filter-class>org.zkoss.zk.ui.http.DHtmlLayoutFilter</filter-class> 
        <init-param> <param-name>extension</param-name> <param-value>html</param-value> 
        </init-param> <init-param> <param-name>compress</param-name> <param-value>true</param-value> 
        </init-param> </filter> <filter-mapping> <filter-name>zkFilter</filter-name> 
        <url-pattern>your URI pattern</url-pattern> </filter-mapping> -->
    <!-- //// -->

    <!-- ///////////// -->
    <!-- DSP (optional) Uncomment it if you want to use DSP However, it is turned 
        on since zksandbox uses DSP to generate CSS. <servlet> <servlet-name>dspLoader</servlet-name> 
        <servlet-class>org.zkoss.web.servlet.dsp.InterpreterServlet</servlet-class> 
        <init-param> <param-name>class-resource</param-name> <param-value>true</param-value> 
        </init-param> </servlet> <servlet-mapping> <servlet-name>dspLoader</servlet-name> 
        <url-pattern>*.dsp</url-pattern> </servlet-mapping> -->

    <!-- /////////// -->
    <!-- [Optional] Session timeout -->
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>

    <!-- [Optional] MIME mapping -->
    <mime-mapping>
        <extension>doc</extension>
        <mime-type>application/vnd.ms-word</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>gif</extension>
        <mime-type>image/gif</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>htm</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>html</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>jpeg</extension>
        <mime-type>image/jpeg</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>jpg</extension>
        <mime-type>image/jpeg</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>js</extension>
        <mime-type>text/javascript</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>pdf</extension>
        <mime-type>application/pdf</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>png</extension>
        <mime-type>image/png</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>txt</extension>
        <mime-type>text/plain</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>xls</extension>
        <mime-type>application/vnd.ms-excel</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>xml</extension>
        <mime-type>text/xml</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>zhtml</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>zul</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>

    <welcome-file-list>
        <welcome-file>index.zul</welcome-file>
        <welcome-file>index.zhtml</welcome-file>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>zkspringjpaexampleListing.zul</welcome-file>
    </welcome-file-list>
</web-app>


Finally, you can run and see the output as follows
image
You can download the source here


Step 10:


In the above example, we have used XML Configuration to initialize our bean. Normally you declare all the beans or components in XML bean configuration file, so that Spring container can detect and register your beans or components. Actually, Spring is able to auto scan, detect and instantiate your beans from pre-defined project package, no more tedious beans declaration in in XML file.This can be achieved by using context:component-scan element in xml configuration file

References


Now let us convert the above example to Spring Annotation. Thanks to gekkio who helped me to achieved this

There is no change in zul file and its VM. And also there is no change in the interface. We need to just add @Service and @Autowired annotation in the ZkSpringJpaExampleServiceImpl.java file as shown here.


  • import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import org.zkoss.zul.Messagebox;
    @Service
    public class ZkSpringJpaExampleServiceImpl implements ZkSpringJpaExampleService {
    
        @Autowired
        private ZkSpringJpaExampleDao zkSpringJpaExampleDao;


    Now we need to change our applicationContext.xml. Remove the manual declaration of the bean and include auto scan feature.
    context:component-scan base-package="zkMVVM.zKMVVMSpringJPA">
        </context:component-scan>

    In the ZKSpringJPAExampleListVM.java, we have declared as follows
    @WireVariable
        private ZkSpringJpaExampleService zkSpringJpaExampleService;

    ZK @WireVariable injects by name, not by type, so the variable name must be an exact match to the bean name. Note that Spring @Autowired by default injects by type, so the @Autowired variable name can be anything and it will work.  So additionally we need to match the name in the xml file as follows
    <bean id="zkSpringJpaExampleService" class="zkMVVM.zKMVVMSpringJPA.ZkSpringJpaExampleServiceImpl"   />

    Alternate method as follows

    You can customize names by adding them to the annotations. For example:
    @Service("zkSpringJpaExampleService")
    public class ZkSpringJpaExampleServiceImpl ...
    Now the bean gets registered as "zkSpringJpaExampleService", so that should be the variable name:
    @WireVariable
    private ZkSpringJpaExampleService zkSpringJpaExampleService;

    You can download the source here
  • 4 comments:

    1. very good explanation, this is very helpful for beginner like me

      ReplyDelete
    2. Thanks a lot, i was finding how to inject with @WireVariable , and ever it give me NullPointer, and now know that i have to use @VariableResolver with MVVM Pattern Thanks a lot :D

      ReplyDelete
      Replies
      1. Hello I have the same problem, do I need to change MVC to MVVM?

        Delete
    3. please tell me how to fix this error "Cannot open URL"

      ReplyDelete