Tutorial
Tutorial
0 (May 2024)
Page 1
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 2
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
List of contents
1 Introduction.....................................................................................................................................6
2 Preface.............................................................................................................................................7
3 Installation.......................................................................................................................................8
4 List of provided plug-ins.................................................................................................................9
5 General architecture – patterns and idioms...................................................................................11
6 Creating a new project...................................................................................................................13
7 The JBizMo project navigator.......................................................................................................24
7.1 Maintenance of general project data......................................................................................26
7.2 Data source settings...............................................................................................................26
7.3 The persistence unit...............................................................................................................27
8 Model the domain..........................................................................................................................29
8.1 Create a domain object..........................................................................................................29
8.2 Adding attributes to domain objects......................................................................................31
8.3 Create an enumeration...........................................................................................................38
8.4 Domain object associations...................................................................................................39
8.4.1 The many-to-one association.........................................................................................39
8.4.2 The many-to-many association......................................................................................40
8.4.3 The one-to-one association............................................................................................42
8.4.4 The one-to-many association.........................................................................................44
8.5 References to domain objects in other sub-packages............................................................46
8.6 Inheritance.............................................................................................................................48
8.6.1 Single table per class......................................................................................................48
8.6.2 Table per concrete class hierarchy.................................................................................50
8.6.3 Table per sub-class.........................................................................................................50
8.6.4 Non-entity base class.....................................................................................................50
8.7 Property sheets.......................................................................................................................51
8.7.1 Property sheets for domain objects................................................................................51
8.7.2 Property sheets for domain attributes.............................................................................53
8.7.3 Property sheets for domain associations........................................................................55
8.8 Tagging..................................................................................................................................57
8.8.1 Documents.....................................................................................................................58
8.8.2 Authentication and authorization...................................................................................59
8.8.3 Mandating......................................................................................................................61
8.8.4 Logging..........................................................................................................................63
8.8.5 Saved queries.................................................................................................................64
8.9 Reverse Engineering..............................................................................................................65
8.9.1 Default namespace selection..........................................................................................66
8.9.2 Database import.............................................................................................................66
8.9.3 Domain model validation...............................................................................................66
8.9.4 Display the results in the Reverse Engineering editor...................................................66
8.9.5 Adapting the initial domain model.................................................................................67
8.9.6 Filtering and mapping....................................................................................................71
8.9.7 Saving the domain model...............................................................................................72
8.10 The JPA query editor............................................................................................................72
9 The database..................................................................................................................................74
Page 3
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 4
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 5
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
1 Introduction
Since Java EE 5, it became very easy to develop multi-tier Java enterprise applications. However,
there is still much effort required in order to create the full application-stack from scratch. The basic
design methodology JBizMo follows is the model driven architecture (MDA). That means that we
extract a static domain model from the software requirements analysis and create that model
graphically by using JBizMo's domain editor. As we can see in subsequent chapters this model
represents the base for further artifacts we may design and create.
Page 6
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
2 Preface
Since 2005, I have been working now on JBizMo. Many hours in my spare time were necessary to
design and to create the result that is now accessible, adaptable and usable by the community. I am
aware of the fact that many people will complain about features, architectures in use, documentation
and generated sources. But for some people – and I hope for a lot of people – it will help to create
Java enterprise applications faster, easier and with higher quality.
Page 7
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
3 Installation
JBizMo provides an update-site to easily integrate it into Eclipse. Open your IDE and select “Install
new software” in the “Help” menu of Eclipse. A dialog opens where we have to select the repository
to install JBizMo from. Click on the “Add” button to create a new repository.
The “Add repository” dialog contains two fields that we have to fill out. Enter “JBizMo” into field
“Name”.
The update-site URL http://jbizmo.sourceforge.net/eclipse/ must be entered into the second field
“Location”.
Now, we just have to select “JBizMo”. After clicking on button “Next”, Eclipse will search for
plug-in-dependencies. Depending on your specific installation, it might take some time to find and
to install them.
In 2013, JBizMo was also added to the Eclipse Marketplace which provides an easy way to install
plug-ins into the Eclipse ecosystem.
Note that the current version of JBizMo was developed and tested with Eclipse 2022-12 and Java 17
SDK.
Page 8
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
• net.sourceforge.jbizmo.model
This plug-in provides the meta-model of JBizMo. It contains Ecore-files and the Ecore-diagram-
files in order to change or to extend the meta-model. It is highly advisable that changes concerning
the model structure are done within the corresponding diagram.
• net.sourceforge.jbizmo.resource
Common images and static libraries for server and client side are located in this plug-in.
• net.sourceforge.jbizmo.service
This plug-in provides high level service methods for different kinds of internal meta-model classes.
• net.sourceforge.jbizmo.shared
The plug-in contains a set of generic widgets that are used internally.
• net.sourceforge.jbizmo.tools
In order to query the target database by using SQL and to check JPA query statements instantly, this
plug-in has been created. Thus, further external tools are not necessary for these purposes.
Furthermore, there are tools for synchronization of the database model with the target database,
services that encapsulate JDT calls and utility classes for protecting manual source code changes
from being lost when rebuilding generated classes.
• net.sourceforge.jbizmo.ui
This plug-in contains classes for the JBizMo project navigator, common dialogs and a wizard to
create a new JBizMo project.
• net.sourceforge.jbizmo.ui.test
This plug-in contains some SWTBot unit tests to check the basic functionality of JBizMo.
Page 9
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
• net.sourceforge.jbizmo.diagram.domain
This plug-in provides the domain diagram editor that is based on GMF.
• net.sourceforge.jbizmo.generator
• net.sourceforge.jbizmo.internal.buildtest
In the past, it was hard to test new features, bug-fixes and improvements. This plug-in helps to ease
that problem by providing automatic build tests upon internal, predefined projects.
The build process can be initiated by running the “Perform JBizMo build test” action in the
Package Explorer view of Eclipse.
Page 10
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
• Domain Object
A domain object in problem solving and software engineering can be thought of as a conceptual
model of a system which describes the various entities involved in that system and their
relationships.
In JBizMo all domain objects are mapped to an abstract or non-abstract JPA entity, a mapped-
superclass or an enumeration. An application designer is able to create domain objects, associates
them via different kinds of relationships and adds attributes to domain objects. The terms entity
bean, entity and domain object will be used synonymously within this manual.
• Repository
A repository provides a way to manage the data access logic in a central location. The plug-in
generates one repository for every abstract and non-abstract domain object. The application
designer cannot directly influence the methods being created by the plug-in. Beside of the methods
that are common for all repositories (e.g. persist, delete, search...), JBizMo creates additional
finder-, getter- and check-methods for every unique key constraint of the specific domain object.
These additional methods will be created for every unique key constraint that consists of two
columns at most!
There is currently no support for more than two columns as generated method names would be
simply too long! Typically, repositories won't be accessed directly by the client!
• DTO
The data transfer object pattern has been already introduced from the very first of J2EE and
represents just a simple data container that provides state but no behaviour. A DTO is used to collect
all data that is necessary for a remote operation. In the days of Jakarta EE many developers and
application designers came to the conclusion that DTOs are evil and should not be used any longer
as JPA entities are now – in contrast to J2EE entity beans – plain old Java objects (POJO) that can
be easily sent across the network.
Furthermore, data transfer objects are hard to create and to maintain (just think of a DTO that
contains dozens of attributes).
But why is the plug-in's architecture based on such an evil design pattern? First of all, a DTO
provides a special client-side view on data that normally is represented by one or more domain
objects. Hence, the internal domain object structure is completely hidden for the client (information
hiding). In JBizMo the DTO attributes depend on the definition of the client (we will come back
later to that point). This means that the DTO only contains data that is really necessary for a special
client operation or form. Just think of a combobox where a user has to select a customer identified
by his name and id. The customer domain object consists of thirty attributes and ten associations to
other domain objects. The corresponding customer DTO for the list contains maybe just two
attributes (the id and the name). Guess what is faster to load, all customers including all fields and
non-lazy associations or the DTO with those attributes you really need? Another important aspect is
the fact that the application designer doesn't have to create and maintain them manually. As
described earlier, the data transfer objects are model artifacts that will be defined implicitly when
Page 11
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
• Boundary beans
A boundary provides an interface between client and business logic, performs DTO conversion and
invokes application service methods (e.g. repository methods). If the application is deployed on a
server, the boundary is a stateless session bean that offers a remote interface.
• Facade
If a client can work directly with domain objects, it isn’t necessary creating boundary beans,
repositories and most of the DTOs. In these scenarios, all business and persistence logic can be put
together in one service facade class. From a meta-model perspective, a facade is just a boundary
bean. A facade contains all boundary methods and most, but not all, repository methods of a specific
domain object. Only the internal generator treats the meta-model differently and combines data
from boundary beans and repositories in a single class! An advantage of this approach is that the
meta-model can be reused easily for different architectures.
• Integration bean
An integration bean exposes its methods via REST, SOAP, RMI, KAFKA or JMS. Every method of
an integration bean refers to a corresponding boundary bean method.
Page 12
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Now, a new wizard page will be opened to enter general project settings. The field “Project name”
expects a string that is used as a default name prefix for all Apache Maven artifacts and Eclipse
projects that need to be created for a new JBizMo project. The second field “Project code” is mainly
used for the root context of a generated web application.
The field “Boundary mode” determines if a project should use boundary beans or facades. Note that
this setting will be ignored if subsequent settings regarding either client or server platform don't
match (see below). Also, note that this decision must be taken before a project is generated.
Afterwards, it cannot be changed!
The plug-in supports protecting manual changes in generated Java source files from being lost when
rebuilding the respective files. This feature can be turned off with the checkbox “Protect manual
changes” (see chapter 18).
JBizMo always creates appropriate projects including all necessary basic packages at which the
package structure is expected to be fixed. Manual changing of these structures is likely to cause
severe model and build errors. Therefore, it is very advisable not to touch them. Of course, there is
no problem to add additional packages manually! Although these structures are fixed, the names of
the packages can be changed in the following fields (e.g. “Domain Package”).
The “Sub-packages” field on this page needs a deeper explanation. Here the developer can add sub-
packages to his project. When creating the Eclipse project, the plug-in also creates new model
source files (*.xmi) for every sub-package and adds these packages to all basic packages.
Page 13
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The next wizard page is used to enter database-related data. Currently, the plug-in supports
After selecting the vendor, the developer should provide a valid connection URL, the user name and
the password for the target database he wants to work with. The field “Data source name” refers to
the data source defined within the target application server and will be inserted into the
persistence.xml file.
Moreover, a developer can enter either a default catalog or a schema name. Please consult the
documentation of the selected database if it supports either catalogs or schemas.
In contrast to former versions of JBizMo, it is now necessary to provide respective JDBC driver
libraries as some database vendors restrict redistribution of these files. You can omit this step but
the plug-in won't be able afterwards to provide some features like synchronizing or querying the
target database without having an appropriate driver in place. The JDBC driver library file(s) can
also be selected after creating a new project (see below).
Note that the database vendor cannot be changed after a new project has been created! Nevertheless,
it is possible to change the database vendor manually in the respective resource file. If we do so, it
Page 14
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
is likely that we will get wrong column types in DDL commands of domain objects that have been
created before we changed the database vendor!
Database settings
In the next wizard page, the developer can enter global application data. In the first group, he selects
the client technology that should be used. Currently, a developer may select:
If we choose RAP, we will have to install a proper RAP target runtime! JBizMo has been tested
with RAP e4 target runtime version 3.28. For more information about how to install the RAP
runtime please follow this link!
The option “NONE” makes sense if either a Jakarta EE or a Spring Boot application should be
created that doesn't require a generated graphical user interface.
Furthermore, the developer can enter the name of the application and the name of the client
package.
Page 15
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
In the second group server-related settings can be made. Currently, the developer is able to select
JBOSS (tested with WildFly 27), GLASSFISH (tested with Payara 6.2023.2) or TOMCAT as the
target platform.
Moreover, we may select NONE to build projects that just run locally in an unmanaged environment
without using an application server. This option is only available for RCP, Swing and JavaFX
clients. In this case, applications will use EclipseLink (version 4.0.1) as persistence provider. This
option especially makes senses for applications that
For Vaadin applications we can select either a supported Jakarta EE server (see above) or Tomcat. A
full overview about all supported and tested configurations illustrates the following picture:
Supported configurations
In the next field “Deploy directory”, the user can insert the path of the server where a Jakarta EE
Page 16
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The next page contains fields for maintaining integration-related project settings. In the panel
“XML binding” a developer can enter a specific XML namespace name as well as a XML
namespace prefix. While the XML namespace name field requires an input the field for the
namespace prefix can be left blank! In subsequent chapters, we will see that it could be necessary to
supply data transfer objects with JAXB annotations. The combobox “Mapping strategy” can be
used to control if these annotations should be either suppressed, created on demand or added by
default. On the other hand, it is not possible to control this behaviour for a single data transfer
object!
While most generation details are implemented in respective generators the developer is able to
define a global mapping type in combobox “Mapping type”. The possible values are ATTRIBUTE
and ELEMENT. If ATTRIBUTE is selected, the generator will add (if applicable) a respective
Page 17
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
annotation that maps a field to a XML attribute. When selecting ELEMENT, all fields of a data
transfer object are mapped to XML elements.
The panel “Module definition” contains different fields for adding integration modules based on
different technologies. Basically, an integration module contains beans that expose boundary
methods via REST, SOAP, RMI, KAFKA or JMS. The possibility of defining one or more integration
modules depends on settings made in the previous wizard page. If the final application should run in
an unmanaged environment (see field “Platform”), an integration module cannot be defined! In case
of Jakarta EE, an integration module can be defined for either REST, SOAP, RMI or JMS. If the
target platform technology is Spring Boot the supported technologies are REST, SOAP, KAFKA and
JMS!
Usually, an Angular application uses REST in order to communicate with the back-end. Thus,
JBizMo will force the creation of a REST module in this case!
When selecting an integration module checkbox (e.g. “Add SOAP module”), the corresponding
detail fields in the respective panel (e.g. “SOAP”) will be enabled. For every selected integration
module it is possible to overwrite the default package name (e.g. “integration.soap”).
By default, the checkbox “Add security handler” is selected. In most cases, it seems to be
reasonable to keep this setting as the generator will later generate a respective handler file. This
handler is responsible for extracting user credentials from a request and authenticates the user by
using the application's login mechanism. If this file isn't in place it is very likely that all boundary
method invocations will fail at runtime if the application is secured.
Furthermore, the developer may select if a client artifact should be generated when building the
project. A client artifact represents a project within the Eclipse workspace that in turn contains
classes that can be used to interact with the respective services from another Java application.
If the generated integration client should be used in a managed environment (e.g. Jakarta EE or
Spring Boot) it makes sense to let JBizMo create producer classes as they facilitate the injection of
the service interface into another managed bean.
Page 18
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 19
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
If checkbox “Add Selenium test module” won't be selected a GUI test module will not be added to
the project. Note that a GUI testing module cannot be added after the project has been generated.
The field “Package” is used to enter the root package name for all generated GUI tests. As JBizMo's
GUI testing strongly depends on Selenium it is important to select the browser in which the tests
should be executed. The combobox provides a list of all currently supported browsers. By pressing
button “Browse” the path to the respective Selenium driver can be selected. The three following
fields “Implicit wait time”, “Page load timeout” and “Maximize window” represent basic
configuration properties for the Selenium WebDriver. As soon as JBizMo creates the GUI testing
artifact it also stores a file that contains global configuration properties. The values entered in the
three aforementioned fields are added to this file (see chapter 16.5). The value entered in field “Test
case suffix” controls the default name of a new GUI test.
The build configuration page provides a combobox containing supported build tools and a table
with detailed information about the proposed artifacts.
JBizMo was always shipped with all third-party libraries that were necessary in order to either
create or build different kinds of projects. By introducing version 2.0 nearly all third-party libraries
are gone and the functionality for providing those resources has been handed over to the build tool.
Page 20
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
While previous versions of JBizMo have provided support for Apache Ant, version 4.0 only
supports Apache Maven!
Due to internal restrictions, JBizMo currently does not use Apache Maven for Eclipse RCP and
Eclipse RAP projects. If the project contains other artifacts the Eclipse application directly depends
on, they are able to provide a respective library that is copied to the library folder of the Eclipse
project as soon as the build process has finished. Thus, it is necessary to rebuild that artifacts on a
regular basis in order to provide all classes that are required by the GUI of an Eclipse application.
Depending on inputs made in previous wizard pages the plug-in creates an initial build
configuration and displays it in a table.
Every row in this table represents an artifact that is later used for creating a project in the Eclipse
workspace. The first column contains the name that can be easily changed by clicking on the
respective table cell. Initially, the plug-in creates a name that is a combination of the project code
(see chapter 6) and a suffix that depends on the given artifact type. If the name is changed manually,
the plug-in will perform validation checks (e.g. the names must be unique and the current
workspace must not contain a project with the same name). The next column contains the name of
the artifact type.
Currently, JBizMo supports following artifact types:
• DOMAIN: Artifact that includes domain classes, the meta-model files and JPA
configuration files (e.g. persistence.xml).
• SHARED: The generator places all enumerations into this artifact. It also provides a
suitable place to add classes that are needed for all other modules.
• DATA_EXCHANGE: Contains classes for data exchange operations (incl. mapping files).
• SERVICE: Includes classes for application services like logging and saved queries.
• SERVER: Artifacts of this type are responsible for creating server deployment files (*.war).
This artifact type is only used in case of rich-client applications!
Page 21
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
• SOAP_SEI: Contains the service endpoint interfaces for all SOAP integration services. This
artifact is only available if the respective build module is selected (see above).
• REST_SEI: Contains the service endpoint interfaces for all REST integration services. This
artifact won't be created if the corresponding REST_CLIENT artifact should be omitted for
this integration module!
• RMI_SEI: Contains the service endpoint interfaces for all RMI integration services.
• KAFKA_SEI: Contains the service endpoint interfaces, the Avro IDL files and the
generated Avro classes for all Kafka services.
• JMS_SEI: Contains the service endpoint interfaces that are implemented by JMS clients.
• SOAP_IMP: Includes all SOAP service implementation classes and the respective security
handler.
• REST_IMP: Includes all REST service implementation classes and the respective security
handler.
• SOAP_CLIENT: This artifact can be used by Java applications that want to consume the
respective SOAP services.
• REST_CLIENT: This artifact can be used by Java applications that want to consume the
respective REST services. Internally, the artifact is based on RESTEasy to interact with the
provided REST resources.
• RMI_CLIENT: This artifact can be used by Java applications that want to consume the
respective RMI services.
• KAFKA_CLIENT: This artifact contains classes for sending messages to Kafka topics.
This provides a way for interacting with the generated Kafka message consumer classes in
the KAFKA_IMP artifact.
• JMS_CLIENT: This artifact contains classes for sending messages to JMS destinations.
• SELENIUM_TEST: Contains all test cases, test suites and necessary configuration files for
GUI tests.
Page 22
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The following picture depicts the distribution of integration artifacts within different architecture
levels:
Integration artifacts
Basically, the *_SEI and *_CLIENT artifacts just provide a convenient way for other Java
applications consuming the integration services of our application. In the case of REST, SOAP and
KAFKA, it is, of course, possible to invoke our service methods in non-Java applications without
being forced to make use of the *_SEI and *_CLIENT artifacts!
Please note, that integration artifacts are not contained in the default build configuration if the
application settings made in previous wizard pages prevent the creation of a given integration
technology!
By clicking on button “Finish” the wizard closes and builds the project within the current
workspace. After this operation has been finished, a new project should appear in the Package
Explorer of Eclipse without compilation errors. It has to be mentioned here that errors and warnings
highly depend on compiler preferences of Eclipse!
Page 23
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Once the view has been opened, it will scan all open projects in the current workspace and adds
every JBizMo project as top-level tree item to the view.
By performing the view's toolbar refresh action, the plug-in searches for new JBizMo projects,
loads the current meta-model into memory and completely rebuilds the tree view.
It's very important to note at this point that the project navigator as well the graphical domain
diagram editor (see chapter 8) are completely separated clients that work in parallel against the
meta-model resource files. That means that changes being made by a diagram domain editor are not
Page 24
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
automatically reflected in the project tree view and vice versa. But this easily could lead to model
inconsistencies. In order to avoid such critical situations, all tree view actions that might lead to
updates of the underlying model resource files are prohibited as long as even one graphical domain
editor is open!
Whenever a domain editor save action is performed by the developer, the navigator view will be
refreshed automatically!
Page 25
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Note that changes to project and package names highly depend on the re-factoring capabilities of
Eclipse! We also use the dialog to create new sub-packages and diagram editors respectively. It is
also possible to change XML binding-related data.
Page 26
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
By pressing Test, we can check if the plug-in is able to connect to the selected database. In this
dialog, we are also able to either add new or remove existing JDBC driver libraries.
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
version="3.0">
<persistence-unit name="_default">
<jta-data-source>java:app/jdbc/testDS</jta-data-source>
<properties>
<property name="eclipselink.id-validation" value="NULL"/>
<property name="eclipselink.cache.shared.default" value="false"/>
</properties>
</persistence-unit>
</persistence>
The persistence unit name “_default” must not be changed as some parts of the framework rely on
it!
A developer is able to change the persistence.xml file manually. Alternatively, the plug-in provides a
dialog to maintain persistence unit properties.
Page 27
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Note that it is the developer's responsibility to provide valid properties and property values! The
plug-in will automatically rebuild this file if a developer changes the data source name or the
persistence unit properties in the corresponding dialogs.
Page 28
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Although JBizMo maps domain objects to JPA entities, the model editor is not a JPA editor!
Therefore, one cannot expect that either the graphical editor or other plug-in components fully
support all features of the JPA standard (e.g. composite primary keys)!
Page 29
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
A further very important aspect when working with JPA is the id generation type which tells the
persistence provider how to generate the primary key for this entity at runtime. The developer
selects an id generation type and may enter (depending on the selected type) further data like initial
value and block size using the respective controls of tab-page “ID generator”. The number of
available items and the default value of the “ID generator type” combobox depends on the selected
database vendor! For example, current versions of MySQLTM doesn't support sequence objects.
Thus, the respective item isn't available in this list.
Our first domain object should be a Country with id generation type NONE. If we click on the
"OK" button, the dialog will be closed and the domain object appears in the graphical editor.
Page 30
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 31
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
After pressing the "OK" button, the plug-in automatically generates a Java class in the package
base:
@Entity
@Table(name = "country_tab")
@NamedQueries
({
@NamedQuery(name = Country.NQ_DELETE_ALL,
query = "delete from Country a"),
@NamedQuery(name = Country.NQ_DELETE,
query = "delete from Country a where a.code = :code"),
@NamedQuery(name = Country.NQ_GET_ALL,
query = "select a from Country a"),
@NamedQuery(name = Country.NQ_FIND,
query = "select a from Country a where a.code = :code"),
@NamedQuery(name = Country.NQ_CHECK,
query = "select count(a) from Country a where a.code = :code"),
@NamedQuery(name = Country.NQ_COUNT,
query = "select count(a) from Country a"),
})
public class Country
{
@Generated
public static final String NQ_DELETE_ALL = "Country.deleteAll";
@Generated
public static final String NQ_GET_ALL = "Country.getAll";
@Generated
public static final String NQ_FIND = "Country.find";
@Generated
public static final String NQ_COUNT = "Country.count";
@Generated
public static final String NQ_CHECK = "Country.check";
@Generated
public static final String NQ_DELETE = "Country.delete";
@Id
@Column(name = "code")
@Generated
private String code;
Page 32
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
/**
*Default constructor
*/
@Generated
public Country()
{
}
/**
*Constructor using fields
*@param code
*/
@Generated
public Country(String code)
{
this.code = code;
}
/**
* @return the code
*/
@NotNull(message = "Field \"code\" must not be null!")
@MaxLength(value = 5, message = "Field \"code\" must have a maximal length of 5!")
@Generated
public String getCode()
{
return this.code;
}
/**
* @param code the code to set.
*/
@Generated
public void setCode(String code)
{
this.code = code;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Generated
@Override
public boolean equals(Object obj)
{
if(this == obj)
return true;
if(obj == null)
return false;
if(getClass() != obj.getClass())
return false;
if(getCode() == null)
{
if(bean.getCode() != null)
return false;
}
else if(!getCode().equals(bean.getCode()))
return false;
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Generated
@Override
public int hashCode()
Page 33
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
{
return getCode().hashCode();
}
/**
* Validate the object before performing an update or persist operation
*/
@PreUpdate
@PrePersist
@Generated
protected void validate()
{
final var validator = new BeanValidator(this);
validator.validate();
}
}
Beside of features like proper annotations, a default constructor, a constructor with a primary key
attribute, the attributes and their respective getters and setters, there are further artifacts that the
generator adds to the class. First of all, a bunch of named queries and suitable name constants are
generated.
In many situations (e.g. within the collections framework of Java), it is very important to provide
well-implemented hashCode() and equals() methods. Both will be created by the plug-in by
using the primary key attribute.
In order to check values of domain attributes, an annotation based entity validation methodology
has been added to the JBizMo framework. Different validation annotations are provided by the
framework to check null-ability, length and even content of a String via regular expressions. The
annotations have to be placed on the respective getter methods. The validation itself will be
performed by the generated validate() method which is called every time before any persist or
update operation is invoked upon this domain object.
Alternatively, the respective annotations of the Jakarta Bean Validation framework (JSR 303) are
used if the project was created with this option (see chapter 6)!
Since version 2.0, JPA supports the creation of type-safe queries in combination with a canonical
meta-model for entities. JBizMo automatically creates a canonical meta-model for all persistent
domain objects. The generator recreates this file (e.g. Country_.java) as soon as the developer
changes the meta-model of a domain object (e.g. Country) by adding or removing an attribute or
an association.
@StaticMetamodel(Country.class)
public class Country_
{
@Generated
public static volatile SingularAttribute<Country, String> code;
@Generated
public static volatile SingularAttribute<Country, String> name;
The next two checkboxes “Insertable” and “Updatable” define if an attribute is part of an insert or
Page 34
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
update operation. If an attribute is marked to be not updatable, it cannot be changed by JPA update
or merge operations.
Per default, the checkbox fields “Set date on persist” and “Set date on update” are disabled. As soon
as a developer selects a type java.util.Date or java.util.GregorianCalendar, both
fields will be enabled automatically. In many projects, it is very likely that some date fields should
be set by the system without client interaction. Just think of a creation date or the last update time-
stamp of a persistent object. If at least one of both checkboxes is selected, the plug-in will generate
an entity callback listener that fills the attribute with an appropriate value when the domain object is
either persisted or updated. The creationDate attribute is a good example for a field that is
insertable but not updatable.
public class CountryCallbackListener
{
/**
* Method to be executed before persisting a country object
* @param object the country object
*/
@PrePersist
@Generated
public void doPrePersist(Country object)
{
object.setCreationDate(new GregorianCalendar().getTime());
}
/**
* Method to be executed before merging a country object
* @param object the country object
*/
@PreUpdate
@Generated
public void doPreUpdate(Country object)
{
}
}
When the entity manager attaches an entity bean to the persistence context, all attributes are
initialized with their respective values loaded from the database. In JPA this is called eager loading.
There might be situations (e.g. handling blob-fields) where one or more attributes should be loaded
on demand only. This is also known as lazy-loading which can be enabled by deselecting the
checkbox “Fetch type eager”. Keep in mind that the JPA specification (Version 1.0 and 2.0) states
that a persistence provider is not forced to pay attention to this setting as those fields might be
loaded eagerly even if they are annotated with @Basic (fetch=FetchType.LAZY).
The optimistic locking capability of JPA offers a great opportunity to protect entity beans against
concurrent modifications. The term optimistic locking means that we are optimistic that concurrent
modifications on an entity don't happen very often. The opposite of this pattern is called pessimistic
locking where an entity bean has a high concurrent write contention.
To enable optimistic locking in JPA an entity bean needs an attribute that is annotated with
@Version. This can be achieved by adding a new attribute of type int, Integer, long or Long
Page 35
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
In many cases, a domain object represents a target of a domain association (see chapter 8.4). When
generating the client and other artifacts, JBizMo is not aware what attribute should be used as a
visual representation of the referenced domain object. If no further information is provided, JBizMo
will always take the primary key attribute for that purpose. This default behaviour can be
overwritten by selecting the field “Display attribute”. If we choose this option, the respective field
will be used in order to represent an instance of a domain object to the end user.
As an example, think of a simple client form for a given domain object that references another
domain object. To keep the things simple, we assume that the referenced domain object can be
selected by a combobox. If no display attribute for the referenced domain object is selected, the
items might be filled with auto-generated numbers of the referenced domain object's primary key
field. But with a display attribute in place the items of the combobox will provide a much more
meaningful interpretation of the objects that are added to that form field.
If the checkbox “Display attribute” is selected, the checkbox “Unique” is selected automatically. In
most cases, it makes sense that this attribute is also unique. But the developer is also able to create
non-unique display attributes! Display attributes must be always of type String! It is not possible
to define more than one display attribute in an inheritance hierarchy!
One of our fields may represent an image or the text of a large document. The @Lob annotation is
used to map these large object types. The corresponding checkbox “Lob” must be selected to create
such an attribute that must be of type byte[] or Byte[]. Although it is not guaranteed by the
persistence provider to initialize such fields on demand only, it is probably best to mark the fetch
type as lazy, since you usually won't access these large objects very often when interacting with the
entity bean.
The next fields in tab-page “Database mapping” are used to enter database-related information.
After entering the attribute name, the “Column name” field will be filled with an appropriate default
value (e.g. attribute name creationDate will be converted to creation_date).
By entering or selecting the attribute type the combobox “Column type” will be filled with
supported database column types of the selected database vendor.
Some database column types may require a length attribute that can be entered into the “Length”
field.
Precision is the number of digits in a number. The scale is the number of digits to the right of the
decimal point in a number. A developer can use the fields “Sale” and “Precision” to specify these
values.
A domain attribute may be selected to be unique by utilizing field “Unique”.
As the name implies, the tab-page “Validation” is used to enter validation settings on field level.
Page 36
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Tab-page "Validation"
The “Future date” and “Past date” fields are prohibited for all types except for java.util.Date
and java.util.GregorianCalendar. If enabled, the field validation processor checks if the
respective value is in past or future (depending on the selection made) and raises an exception if the
validation fails.
In order to specify the minimum and maximum length of an attribute, the fields “Min. length” and
“Max. length” can be used.
The developer defines the maximum and minimum value of an attribute in the “Min. value” and
“Max. value” fields. For example, the age attribute of a human being domain object can be easily
supplied with a constraint that the minimum value is 0 and the maximum value is 130. The
following code snippet demonstrates the result of our definition:
@MinIntegerValue(value=0,message="Field \"age\" (rest omitted)")
@MaxIntegerValue(value=130,message="Field \"age\" (rest omitted)")
@Generated
public int getAge()
{
return this.age;
}
Another powerful kind of validation represents the adoption of regular expressions that can be
maintained in field “Regular expression”.
“Nullable” is the last field in that dialog and defines if an attribute may be null! This setting is not
supported for primitive types (e.g. int)!
For fields of type String it is often desirable to remove leading or trailing whitespace characters
before saving them in the database. This behaviour can be controlled using the corresponding field
in tab-page “Conversion”. Furthermore, it is possible that a String will be automatically converted
to upper-case or lower-case. For all other mapping types these fields are always disabled! If one of
the checkboxes is selected the generator will add respective conversion code in boundary, facade,
integration and data exchange methods.
Tab-page "Conversion"
Page 37
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The enumeration is now ready for adding some literals to it. Again we go to the editor's palette and
drag some “Enumeration literal” elements that we afterwards drop on the newly created enum. In a
dialog we are requested to enter a valid literal name (e.g. NO_RESTRICTION,
EXPORT_RESTRICTION, IMPORT_RESTRICTION).
In order to add new attribute countryState that makes use of this type, we have to draw an
“Enum association” from the domain object Country to CountryState. As soon as we finish this
operation, we are requested to enter the name of the new attribute. Note that associations of this
kind are supported only from a domain object to an enum. The reverse direction wouldn't make
sense and is not possible. The term association refers to the connection line between the domain
object and the enumeration. However, the type Country just gets a new attribute:
@Enumerated(EnumType.STRING)
@Basic(optional = false, fetch = FetchType.LAZY)
Page 38
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Beside of attribute and column name, the user is able to select if this association is optional. If we
select that this association is optional, it will be possible to have Address objects without
referencing a Country.
As we have discussed earlier, JPA supports loading data on demand. In order to enable lazy-loading
for this association, we would have to deselect the “Fetch type eager” checkbox.
At first glance, it seems advisable to enable lazy-loading for every many-to-one association. Keep
in mind that this could lead to severe consequences concerning heap-space and performance as the
JPA provider might create special proxy objects for every entity bean instance additionally to load
Page 39
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
/**
* @return the country
*/
@NotNull(message = "Field \"country\" must not be null!")
@Generated
public Country getCountry()
{
return this.country;
}
/**
* @param country the country to set.
*/
@Generated
public void setCountry(Country country)
{
this.country = country;
}
Page 40
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
We have to insert a name for the collection-based attribute and a fetch type can be selected. In
contrast to the many-to-one association, it is possible to mark this kind of association as
bidirectional. If we do so, the reverse name must be specified and a collection-based attribute to the
Country class will be added also. But the owner of the association will be still Customer.
From a database perspective, a many-to-many association is mapped to a join table (in our case
customer_countries_tab) that contains two columns (customer_pk and country_pk) that
in turn hold the respective primary key values of the owner and the target table. This join table has
no primary key but we can add a unique key composed of both columns by selecting “Add unique
key”. This can be helpful if our application shouldn't allow saving the same ( Customer/Country)
combination twice (or more).
The plug-in adds following source code to the Customer class:
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "customer_countries_tab",
joinColumns = {@JoinColumn(name = "customer_pk") },
inverseJoinColumns = { @JoinColumn(name = "country_pk")})
@Generated
private Collection<Country> countries = new ArrayList<Country>();
/**
* @return the countries
*/
@Generated
public Collection<Country> getCountries()
{
return this.countries;
}
/**
* @param countries the countries
*/
@Generated
public void setCountries(Collection<Country> countries)
{
this.countries = countries;
}
Page 41
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The following picture illustrates the many-to-many association in the graphical domain editor:
In the dialog we can enter the name of the attribute and the name of the database column.
Furthermore, the fetch type can be specified.
The checkbox fields for all cascade operations are selected by default as it is very advisable that
CascadeType.ALL is used always within the JBizMo framework when dealing with one-to-one
associations.
By default, a one-to-one association is bidirectional and the “Reverse name” field is filled with an
appropriate default value.
The plug-in adds following source code to the Person class:
@OneToOne(fetch = FetchType.LAZY, optional = false, cascade = { CascadeType.ALL })
@JoinColumn(name = "address", referencedColumnName = "id", nullable = false)
@Generated
private Address address;
/**
* @return the address
*/
@NotNull(message = "Field \"address\" must not be null!")
@Generated
public Address getAddress()
{
return this.address;
}
/**
* @param address the address to set.
*/
Page 42
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
@Generated
public void setAddress(Address address)
{
this.address = address;
}
As we have defined that this association should be bidirectional the Address class has been
changed also:
@OneToOne(mappedBy = "address")
@Generated
private Person person;
/**
* @return the person
*/
@Generated
public Person getPerson()
{
return this.person;
}
/**
* @param person the person to set.
*/
@Generated
public void setPerson(Person person)
{
this.person = person;
}
Due to the internal meta-model, the plug-in will draw two connection lines between both domain
objects if an association is bidirectional!
Page 43
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
We have to insert a name for the collection-based attribute and the fetch type can be chosen. The
cascade operations may be set in the following fields. By default, the one-to-many association is
bidirectional. Although we are able to change this setting to unidirectional by deselecting the
checkbox “Bidirectional”, we should keep the default value as unidirectional one-to-many
associations have limited support in subsequent modelling parts (e.g. when defining a client form).
The generated source code in the Person class looks like this:
@OneToMany
(
targetEntity = Phone.class, mappedBy = "person",
fetch = FetchType.LAZY, cascade = { CascadeType.ALL }
)
@Generated
private Collection<Phone> phones = new ArrayList<Phone>();
/**
* @return the phones
*/
@Generated
public Collection<Phone> getPhones()
{
return this.phones;
}
Page 44
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
/**
* @param phones the phones
*/
@Generated
public void setPhones(Collection<Phone> phones)
{
this.phones = phones;
}
Because of the bidirectional nature of this association further source code has been added to the
Phone class:
/**
* @return the person
*/
@NotNull(message = "Field \"person\" must not be null!")
@Generated
public Person getPerson()
{
return this.person;
}
/**
* @param person the person to set.
*/
@Generated
public void setPerson(Person person)
{
this.person = person;
}
Page 45
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
As soon as the Customer entity including a primary key attribute has been created, we may add a
reference or shortcut to Country from the sub-package base. This can be achieved by opening the
diagram's context-menu. If we select “Create Shortcut”, a dialog will appear to select the domain
object or enumeration that should be referenced in this editor.
Page 46
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
If we press the "OK" button, the shortcut will be created and displayed in the graphical editor.
Referenced domain objects are supplied with a small arrow-icon on the lower left corner in order to
indicate that this object doesn't belong to this package originally.
Page 47
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
8.6 Inheritance
In this chapter, we want to discuss the inheritance features the plug-in provides. Although
inheritance is one of the key concepts of object-oriented design, care has to be taken as there is no
equivalent concept in the relational database world. Hence, if we rely too strongly on that design
principle we might face performance problems afterwards. It is also important to note that
inheritance must be specified always when a new domain object is created. A domain object cannot
be selected to be the root of a hierarchy afterwards!
Currently, the plug-in supports three different inheritance types:
Page 48
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Afterwards, attributes and associations can be added to our newly created base class. The plug-in
generates following source code (bold lines are responsible for inheritance):
@Entity
@Table(name = "person_tab")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("NONE")
public class AbstractPerson
We now create some sub-classes that inherit from AbstractPerson. For example, let's define an
Employee that derives from AbstractPerson. We simply create the Employee by dragging a
“Domain object” from the editor's palette. As Employee doesn't represent the root of the hierarchy
we may omit inheritance information like discriminator type, value and column name. In order to
derive Employee from AbstractPerson, we have to select an “Inheritance” element from the
palette and draw a connection line from Employee to AbstractPerson. An input dialog will
request a discriminator value (e.g. “EMP”) for the Employee sub-class.
@Entity
@DiscriminatorValue("EMP")
public class Employee extends AbstractPerson
Page 49
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 50
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The next section “Database properties” displays columns, indexes, primary key and foreign keys
that belong to the selected domain object's database table.
Page 51
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
By performing a double-click on a selected row or pressing menu item “Edit” a dialog is opened
that allows a developer to change database column data:
This section is especially useful in order to create unique keys and indexes manually. For example,
our Customer object should contain a unique key that is composed of the name. We simply have to
select menu item “Add unique key” that opens a dialog which expects a name for the unique key
and the columns to be added to it.
Page 52
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
After saving the changes, it is always advisable to synchronize the repositories in order to let
JBizMo automatically create additional finder- and check-methods!
The tab-page “Keys” contains all foreign keys of the selected database table:
The grid component provides a menu with items for either deleting or renaming an existing foreign
key.
All elements of section “Appearance” are disabled for all kinds of objects in the graphical editor of
JBizMo!
Page 53
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The section “Database properties” displays all column details of the selected domain attribute and
doesn't contain editable fields.
In the “Comments” section it is possible to enter internal and user comments. Whereas internal
comments are only used for documentation purpose the user comments come into play when
generating client forms (see chapter 11). If the user comment field for an attribute contains a text, it
will be used later on to add a tooltip text to a form field that is mapped to the corresponding
attribute.
Page 54
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
For example, we may change the selected association's cascade-types and the fetch type.
Furthermore, a user is able to change the optional, insertable and updatable flags.
In the “Comments” section it is possible to enter an internal and a user comment. As with domain
attributes the user comment is used to generate tooltip texts for respective form fields.
Page 55
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 56
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
8.8 Tagging
When modelling a domain for a specific project, we basically define the technical structure of our
application. Beside of that, it would make sense to enhance the domain model with system-related
information. Just think of the problem that we are already able to model a User entity, but how
should the framework be aware of that in order to integrate this entity seamlessly into the
authorization and authentication services?
In JBizMo the problem is solved by a technique that is called Tagging. In other words, the
framework provides a facility to add further information to entities, attributes and associations in
order to build a bridge between the domain model and system-related services.
Although the plug-in supports Tagging for authorization, authentication, mandating, logging and
documents at the moment, it is very likely that there will be more in future versions of JBizMo.
The entry point for Tagging is always the domain object or enumeration. Note that a domain object
must be tagged always when it is created. The respective dialog provides a field “Tag”. Performing
this operation afterwards is not possible! It has to be mentioned also that Tagging is not supported
for abstract classes or mapped superclasses. Moreover, most tags (e.g. USER or ROLE) may be used
only once within a project! As soon as we have created a tagged domain object (e.g. User), we may
add tagged and untagged attributes and associations just like we would do it with regular entities.
Page 57
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
8.8.1 Documents
In a first example, our application should be able to handle physical files. With JBizMo it is really
easy to integrate handling of files seamlessly. We create a domain object Attachment that is
tagged with DOCUMENT.
There are three mandatory attributes that must be created and tagged properly in order to get full
support for respective functionality:
At first glance, after creating the domain object Attachment including all attributes and
associations we cannot see great benefits of Tagging. But when defining respective client forms (see
chapter 11) JBizMo will provide additional form actions that enable a user to upload and download
physical files.
Page 58
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The domain object that represents the User must provide at least a unique display attribute for the
name, a password, an email address and a flag that determines if the User is active or not. We also
need a Role entity with at least a unique display attribute for the name of a role. We must create a
tagged (USER_ROLE) many-to-one or many-to-many association that defines the roles that are
granted to a user account. Note that all names of tagged domain objects, attributes and associations
are arbitrary.
Next, we have to define a special data transfer object that is responsible for exchanging security-
related data between application layers. Go to JBizMo's project tree view, select the respective
project item, open the context-menu and select “Create log-on DTO”. JBizMo will perform some
checks to validate if the creation of this DTO is possible.
The most important constraints are:
Apart from the log-on DTO the plug-in also adds a logOn() method to the boundary of the User
entity in order to provide an easy authentication service for the client. As soon as this operation is
finished, all client forms will be supplied with security-related source code artifacts when the forms
are created or rebuilt. For example, actions will be added to the toolbar of a dialog depending on the
roles granted to a user:
if(SecurityManager.isCallerInRoles(UserBoundaryService.ROLE_ADMIN))
toolbarManager.add(actionDelete);
if(SecurityManager.isCallerInRoles(UserBoundaryService.ROLE_ADMIN,UserBoundaryService.ROLE_OPERATOR))
toolbarManager.add(actionCreate);
if(SecurityManager.isCallerInRoles(UserBoundaryService.ROLE_ADMINISTRATOR))
toolbarManager.add(actionUpdate);
By default, the plug-in creates two default roles (ADMINISTRATOR and READONLY) when
creating a new project. In most scenarios, these roles are not sufficient enough to cover all different
Page 59
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
authorization strategies that might be necessary. Thus, it must be possible to add further roles. In
order to maintain project specific roles, we have to go to the project tree view, select the respective
project item, open the context-menu and select item “Roles”. A dialog appears to create, edit and
remove roles.
A role consists of a name and two flags “Administrator” and “Readonly”. If we create a new role
and set the flag “Administrator”, this role will be added automatically afterwards when new forms
and form actions are created. Therefore, by default, this role will enable all functions of an
application to any user this role is granted to. On the other hand, if we create a role and set the flag
“Readonly” it will be added automatically afterwards to all forms and form actions that do not
change or delete data.
JBizMo doesn't rely on this simple authentication and authorization client-side strategy solely. In
addition of that, the framework utilizes security features of the application server.
At this point, we don't want to dive too deeply into JAAS ( Java Authentication and Authorization
Service) which is a standardized security specification all Java application server vendors must
implement. Please consult the specification of your vendor how to setup a security domain for your
application.
Page 60
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
8.8.3 Mandating
In many enterprise applications, there is a demand of storing data for different organizational units,
customers or locations (hereinafter referred to as clients) in a shared database. Usually, this is
accomplished by defining a table that contains the different clients as table rows. All relevant
business objects that are intended to be mandated will be supplied with a foreign key to that table.
This allows accurate records being returned for subsequent queries that actually belong to a client.
As with other additional functions (authentication, authorization etc.), JBizMo provides a solution
to realize such tasks easily.
First, we must tag an appropriate domain object with CLIENT. The two attribute tags
CLIENT_ACTIVE and CLIENT_NAME are not used currently but might come into play in future
versions.
An essential prerequisite for the use of mandating in JBizMo is the definition of the domain objects
for user management (see above). The domain object that represents the user (tag USER) must be
also supplied with a non-optional many-to-one association to the client domain object. This
association must be tagged with CLIENT_REFERENCE.
In other words, every user account must be assigned to a client. An assignment to more than one
client is not supported.
Now, we can start creating further domain objects. Once we create a many-to-one association,
which is tagged with CLIENT_REFERENCE, the domain object is considered to be mandated.
However, not all domain objects are equipped with such an association. Typically, there are some
objects that are shared by all clients. JBizMo also includes a mechanism that can automatically
determine a membership to a client. For example, it is sufficient that only the Customer has a
reference to the client. The CreditInfo class is then automatically associated to the client of the
respective customer. A prerequisite is that an object (in this case CreditInfo) has a direct or
indirect (wired via other domain object associations between both objects) and non-optional many-
to-one or one-to-one association to a mandated object.
Page 61
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Another very important tag concerning mandating represents CLIENT_DISPLAY. In many cases, an
application contains mandated master data. This basically prevents the use of a unique display
attribute. Otherwise, a client would possibly interfere creating or maintaining data of other clients
(e.g. due to duplicate customer names). To circumvent this, the developer can define an attribute of
type String and sets the tag CLIENT_DISPLAY. This automatically generates a unique key that
consists of the foreign key column to the table that holds the clients and the column of this attribute.
For the later use of client dialog fields, the content of this attribute will be taken automatically to be
displayed in comboboxes, list of values, proposal text fields and selection lists. If the reference to a
client exists only indirectly, it cannot enforce database keys to be generated! The content of that
attribute is still used for display purposes in the aforementioned fields, but there is no direct way in
order to perform unique checks upon inserted data. This would have to be ensured by manually
added queries!
When creating new mandated objects, the additional form field type SELECTION_BY_CLIENT
emerges. Those fields will be set automatically by the appropriate log-on DTO attribute in
subsequent storage operations.
Hence, this type is very similar to SELECTION_BY_SECURITY_DTO (see page 85).
Also, when using other field types (e.g. proposal text fields, comboboxes etc.) there is an impact
when using mandated domain objects. The boundary or facade methods that fetch list data are
provided with an additional parameter. This parameter is set automatically also in the user interface
and represents the id (primary key field) of the client. In the boundary/facade method itself, this
parameter is used to restrict the result set so that the user only receives objects that are assigned to
the client he belongs to.
When defining search or list views, the developer may choose whether or not the result set should
be restricted automatically. This behaviour is driven by selection list “Data fetch type”. Depending
on the selected domain object, the list may contain three different entries. If we select DEFAULT,
there is no restriction at all and a user is able to search for all objects that are stored in the database.
When selecting USER or CLIENT, an additional parameter is added to the signature of the
respective boundary/facade methods and the number of returned objects is limited accordingly.
Page 62
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
8.8.4 Logging
If the application runs on a server, we can also create a domain object that contains log entries that
are created when accessing boundary/facade methods. JBizMo requires creating an enumeration
that contains the logging levels. The corresponding domain object for logging needs following
tagged attributes:
In addition of that, we must create an implementation of the logging service by executing the
project's navigator “Rebuild logging” action.
Page 63
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The source code of the saved query service must be created by executing the project's navigator
“Rebuild saved query service” action.
Page 64
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Before starting Reverse Engineering it must be checked if the project's data source is configured
appropriately (see chapter 7.2)! In the following chapters, we will describe all steps of the process.
Page 65
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 66
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
been created by the Reverse Engineering process. All new domain objects are added to the
namespace that has been selected initially before opening the editor. The “Database model” area
displays the imported database meta-model.
Page 67
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The domain object's tree view item also provides a context-menu that in turn contains an item to
delete a domain object. But care has to be taken as deleting a domain object will be cascaded
through all domain associations that reference the selected domain object!
A domain attribute can be changed by either performing a double-click on the respective tree item
or by selecting the attribute's “Edit” context-menu item.
The context-menu also offers an item to delete a domain attribute. Note that deleting a primary key
attribute is not supported!
If foreign keys are either missing or not supported, it is even possible to convert an attribute to a
Page 68
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
We can edit and delete all kinds of domain associations. If the owning side of a bidirectional
association is deleted, the reverse side is deleted also.
As the import process always creates many-to-one associations it is possible to either add a one-to-
many association or convert it to a one-to-one association. When converting a many-to-one to a
one-to-one association, JBizMo will always add a reverse association. We may even convert a
many-to-one association to a domain attribute.
The context-menu item “Exchange owner” is only applicable for many-to-many associations!
When importing the database meta-model, it is not possible to infer enumerations. But we may
create them afterwards by selecting the item “Add enum” of the namespace context-menu. If we do
so, a dialog to create a new enumeration is opened.
Page 69
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Beside of the name, an arbitrary number of literals can be added to the new enumeration. The
enumeration can now be used as type when opening the dialog to edit a domain attribute as depicted
in the following picture:
All enumerations, domain objects, attributes and associations that have already existed before
starting the Reverse Engineering process are read-only! Thus, they neither can be changed nor
deleted in the editor!
Page 70
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The first section contains input fields for special domain attribute mappings. If the import process
creates an attribute with the given name it will set internal version and date flags automatically,
provided that the attribute has a suitable type.
The next four fields allow us to filter the tables that should be processed in a comprehensive way.
We may enter an arbitrary number of search strings into every single field. In case of inverted filter
criteria (e.g. don't start with), an AND logic is applied. When performing the search operation, all
filter strings are handled in a case-insensitive manner. We don't have to enter the full name of a table
as the table names are compared by checking if the particular filter string is a prefix of the table
name.
Furthermore, it is possible to define if tables that are referenced via foreign keys should be imported
also.
As soon as we apply the changes we must confirm that the import process should start again
because all manual changes get lost when starting a new import process!
Page 71
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 72
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
As soon as the “Execute” button in the toolbar is pressed an internal JPA engine is started and the
query is performed. If no error has occurred, the result will be displayed in the result panel.
Basically, the JPA query editor supports two different operation modes. When executing a query
that returns an arbitrary number of objects, the result panel displays all persistent objects found in a
hierarchical tree structure where all attributes and associations are added as child items to a
respective object. In case of an association, the corresponding tree item can be expanded in order to
see the objects that are referenced by this association.
Furthermore, it is possible to create a tabular result if the query select clause contains an arbitrary
number of domain attributes separated by a comma.
Page 73
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
9 The database
The following chapter describes basic settings and tools necessary for working with the project's
relational database.
Database properties
One of the most important fields is “Identifier style in target DB”. When modelling a new domain,
the respective database identifiers for table and column names will be initialized with proper default
values. They are stored as entered in respective text fields. The identifier style controls how a given
identifier will be converted in generated DDL statements and JPA mapping annotations. Three
different options are possible:
Page 74
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Note that changing the field's value doesn't change the identifiers saved in the meta-model. Rather,
the presentation in respective source code fragments and DDL scripts will be changed accordingly!
It is always advisable to change this setting only directly after creating a new project. Of course, it
is possible to change it afterwards but this might end up in recreating the full database!
The dialog provides further fields for entering a default schema and a default catalog name, the
Hibernate® dialect, the EclipseLink target database name and some fields that control performing
validation checks upon given database identifiers. On the one hand, the user is able to change the
maximum length of a database identifier (e.g. table name). The field “Identifier regular expression”
is used to enter a regular expression that checks the validity of an entered database identifier. The
tab-page “Reserved words” contains a text field with all reserved words (separated by blanks) of a
given database. If a developer creates a new object (e.g. domain attribute) that is mapped to the
database, he will get an error if the given identifier (e.g. column name) is contained in this list!
Furthermore, we can manually overwrite the default values regarding support of identity columns
and sequences.
The next section contains a list of all available database types. For all supported databases JBizMo
provides a good starting point for mapping domain attributes to database columns. Sometimes it is
necessary to either create new or change existing column types. This is possible by selecting a
respective context-menu item of the list. When opening the dialog to edit an existing database type,
it is possible to adapt the Java type mapping. Furthermore, the selection of checkbox “Omit size
information” can be changed. Sometimes the developer provides a maximum field length when
creating a new persistent domain attribute (see page 31). Normally, this value is used in respective
DDL scripts in order to control the column's length constraint. But depending on the selected
database vendor and database type, sometimes such a value is not expected in the DDL command
and produces an error when executing the DDL statement. In this case, we can select “Omit size
information” in order to avoid the length constraint from being added to corresponding scripts.
Page 75
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
On the right editor side, all suggested DDL script statements are displayed. Every row consists of an
internally used transaction ID, a flag that determines if the statement should be executed or not, a
type that easily identifies what the statement does, a state, the statement itself and a response
message.
Sometimes it might be necessary to change the generated statement. This can be achieved by
performing a double-click on the corresponding row that opens a dialog to manually rewrite the
script statement.
If we press the “Execute” button in the editor's toolbar, the plug-in starts to send every single DDL
statement to our target database. Note that JBizMo only executes statements that are marked
properly (checkbox “Execute” must be selected). If the database was not able to perform an
operation successfully, a detailed error message will be added to the field “Message” and the state
will be set to “Error” in the respective row. It must be mentioned here that JBizMo doesn't create
DDL statements to remove tables that are not (or no longer) part of the domain model! Those tables
shall be deleted manually.
Page 76
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
domain model are displayed. By selecting the context-menu item “Query” of such a table item a
new editor page is opened in the editor area of Eclipse. The editor contains a toolbar, a query input
field, a result list panel and a grid panel that displays feedback messages. Beside of the standard
buttons that are used for executing and saving a query, the toolbar also contains a checkbox that
allows the developer to select if the number of returned objects should be limited. If so, a maximum
number of returned objects can be entered in a text field. The “Auto commit” checkbox controls if
update, insert or delete operations should by committed automatically. The query input field
contains a default select statement when creating a new query. When opening a saved query - which
can be usually found in the “sql” folder of the workspace project that contains the domain objects -
the file content is displayed in the query input field. In addition to syntax colouring, the query input
field also offers a content proposal assistant that is triggered by entering a dot character.
Before executing statements following preconditions must be met:
As soon as the “Execute” button in the toolbar is pressed the statements(s) entered are sent to the
database. If no error has occurred, all recordsets will be displayed in the result panel. When
executing update or insert statements that don't return data, the result panel will be empty!
In any case, the plug-in creates a message for every single statement and displays it in the
corresponding grid panel. Multiple statements (e.g. a couple of insert statements) must be delimited
by using a semicolon.
Page 77
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
@RolesAllowed({ "ADMINISTRATOR" })
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public Country copy(Country sourceObject, Country targetObject) // Rest omitted!
Note that authentication-related settings won't work until respective application server services
(JAAS) are not properly configured. If the application runs in an unmanaged environment, the
selected transaction type and permission mode won't be added to the generated method and
therefore have no effect!
Page 78
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
11 The client
This chapter describes the features of JBizMo to build a fully working client application. The
practice has shown that developing the client shouldn't be started until the domain model has been
created and reviewed.
Note that all screenshots of the sample application made at runtime highly depend on the selected
operating system and the client technology that is used for a particular project. Furthermore, it must
be mentioned that each client technology may implement the given model differently!
The dialog expects a name for this new object. Moreover, we may select roles that afterwards
should be granted automatically to forms and sub-groups that are added to this group. When
pressing the “OK” button, the tree view instantly adds the new form group to the selected parent
group:
The name and the selected roles may be changed afterwards but there is currently no support
relocating a form group within the hierarchy!
Page 79
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Per definition, every form belongs to a form group. Hence, we first have to select a form group in
the project tree view and open its context-menu. In order to create a new single record form, we
have to choose item “Create update form”. When performing this action, an empty dialog appears.
Now, the dialog expects the selection of an existing domain object by entering one or more letters
into the auto-complete field “Domain object”. When a user presses a key, only the domain objects
starting with the selected letter are shown. By entering more characters, the developer can filter
down the list to better matches. As soon as we select Country, the form will be initialized with
appropriate default values for name, title, initial width and height, name of corresponding DTO and
boundary/facade method name.
Checkbox “Add title area” controls if the form should be supplied with a title area. In addition of
that, we are able to define if the form should be modal and/or resizable. If field “Open update after
create” is selected, the plug-in will add source code in order to open a respective dialog to update a
newly created object after this dialog has been closed. This field is enabled for forms of type
CREATE and ADD only!
The field “Return type void” controls if the corresponding boundary method should return void or
the form's data transfer object. If the project is based on facades and this checkbox is selected, the
method will return the persistent domain object. The field “Form DTO” will be visible only if the
project is configured to use the boundary mode.
In previous versions of the JBizMo, a new DTO was created for every single record form. By
selecting the checkbox “Create shared DTO” the same data transfer object is used for all single
record forms of the same domain object which reduces the number of generated data transfer
objects significantly!
Page 80
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The rest of the dialog contains a tab-folder with two tab-pages “Visual Editor” and “Roles”. The list
in page “Roles” contains the roles that may use this form and is initialized with the roles selected in
the corresponding form group. Of course, a developer is able to change the default selection
according to his needs.
Page 81
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Beside of amending the panel's name and label, the user is able to change the relative position by
selecting a different row and/or column. In this example that uses just one panel, it makes no sense
to change the position. Rather, these settings are coming into play if we have more than one panel
on a form. In this situation, a form is divided into a top (Row 1) and a bottom (Row 2) area. Both
areas span over the full width of the form. The height of the first row depends on the highest panel
that in turn depends on the height of all vertically arranged elements. The rest of the form's height is
left over for the second row.
In the case that a row contains more than one panel, we have to define a distinct column index for
every panel. While generating the form's source code a tab-folder will be created for multiple panels
in a row whereas every panel represents one tab-page.
Especially for domain objects with a great number of attributes and associations, it might be
necessary to place the fields on more than one panel. Although the plug-in initially places all simple
fields on one default panel, we may create as many additional form panels as necessary and move
the fields by drag-and-drop on the newly created panels. Every panel in the Visual Editor contains a
context-menu item in order to add a new panel to a form.
It is also possible to delete a panel via the context-menu item “Delete panel”. Note that a panel
cannot be deleted as long as it contains form fields!
Page 82
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
After initialization, a developer is able to change the field's name, label and width in the
corresponding field edit dialog by performing a double-click on the corresponding field in the
Visual Editor:
Furthermore, it is possible to enter a default value. Note that for every date or boolean field a
default value cannot be entered in textual form. Rather, only a checkbox is available. In case of a
date type, a selection of this checkbox means that the field will be initialized with the current date.
The default value fields are enabled for forms of type ADD and CREATE only.
In some cases, it might be useful hiding a form field. This can be achieved by deselecting checkbox
“Visible”. An invisible form field leads to a completely different behaviour in contrast to simply
deleting it. Internally, every form field will be mapped to an attribute of the form's data transfer
object. If we delete a form field, the DTO attribute will be removed too! An invisible form field will
not be added to the form's source code but the DTO attribute remains. By default, JBizMo hides a
form field (in case of forms of type ADD and CREATE) that is mapped to a surrogate id attribute,
that is filled automatically by the persistence provider. This is especially useful when the data
transfer object must be returned after performing a persist-operation and we need to know the id of
the newly created object in order to perform further actions upon it.
A form field can be also made invisible in the Visual Editor by performing the “Hide” action of the
field's context-menu.
As the Visual Editor should render the form model as precisely as possible the invisible fields are
not displayed in the respective panel. But the dynamic context-menu of the form panel is aware of
all invisible fields that belong to the panel and provides an “Edit field” action for every hidden field.
When performing this action, the respective edit form field dialog is opened.
The layout of a panel that contains simple form fields follows a simple grid-layout scheme at which
a panel may contain one or two columns and a random number of rows. By default, a panel only
contains just one column, but we can move fields into a second column by selecting checkbox
Page 83
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
“Second column”. The row index “1” represents the topmost position of a panel. By editing the
field “Row index” we may change the vertical position of a form field. Increasing the index moves
the field down.
If checkbox “Span” is selected, the field will ignore the specified width and will span over both
columns of a row. Note that this selection has no impact on forms of JSF clients as this feature is
basically not supported by this technology.
The following picture illustrates the grid-layout scheme:
The layout of the form fields can be also changed easily by using drag and drop in the Visual Editor.
If the position of two fields should be exchanged, we can simply drag the field label and drop it on
the label of the desired field. The Visual Editor refreshes the layout and both fields will be placed on
their new positions. It is also possible to drag a visible field to an empty placeholder in the panel's
grid-layout. These placeholders appear as yellow marked areas as soon as a form field is dragged
over.
When performing the “Add row” context-menu action, the Visual Editor creates additional
placeholder areas at the bottom of the panel to which existing fields can be dragged to. As soon as
the Visual Editor is refreshed the new row disappears if no field has been moved to it!
By analysing the domain model data JBizMo is able to infer if a user is obliged to enter data for a
given field. This information is depicted in field “Mandatory”. We are able to overwrite this setting
but care has to be taken as the plug-in doesn't validate if a manually changed entry might cause
problems at runtime!
The field “Readonly” controls if a form field can be changed by the user at runtime. The default
value can only be changed for fields that belong to forms of type UPDATE!
If the field represents a combobox, a LOV or a proposal text field (see chapter 11.2.4), it is possible
to change the value of field “Add detail link”. If the field is selected, the generator will add a link to
the field's label. When following the link at runtime, it will open a corresponding read-only form of
the referenced object.
As soon as every field and other form-related data fit our needs, we may create our first form by
pressing the "OK" button. Beside of the form, further meta-data objects and source code for
boundary/facade method and corresponding form DTO are generated by JBizMo. The form DTO
will be omitted if the project is based on facades!
The following picture shows the new form for creating Country objects at runtime:
Page 84
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
It must be mentioned at this point that this tutorial cannot discuss the generated code. Only this very
simple example results in some hundred lines of code in different classes for GUI and business
logic!
Page 85
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
1.) COMBOBOX
By default, a many-to-one association is mapped to a combobox which references a separate list
DTO (e.g. CountryListDTO). The DTO contains at least the primary key attribute of the
referenced domain object (in this case Country). If the referenced entity contains a display
attribute, a second attribute will be added to the DTO. As the name implies, a display attribute is
used as visual representation of the referenced object in the combobox field. This kind of
component should be used only if the number of referenced objects is not too high as the client
always tries to fetch all objects at once when a form is initialized at runtime. For security reasons,
the number of returned objects is limited by the respective boundary/facade method.
2.) LOV
A list of values is a special kind of a list view that will be discussed in detail in a later chapter. It
represents a good alternative to comboboxes as the user must search for a suitable reference object
manually by using the list of values dialog. Therefore, automatic bulk fetch operations are not
performed by the client (c.f. combobox)!
3.) SELECTION_BY_SECURITY_DTO
In some situations, an entity references a domain object that represents the application user. For
example, we want to know what user has created the Country. Thus, we add a new many-to-one
association from Country to User. In the client this reference should be set automatically without
user interaction. If we have proper security-related settings (via Tagging) in place, we will be able
to select this field type, which has no visual representation.
4.) SELECTION_BY_PARENT_FORM
This type isn't visible also and will come into play if we work with bidirectional one-to-many
associations in the client. For example, we have a CustomerOrder and an OrderLineItem
domain object and a CustomerOrder consists of a random number of OrderLineItem objects.
In our application we need a form to add new OrderLineItem objects to a given
CustomerOrder. If we choose this type, the association (e.g. customerOrder) will be set
implicitly when initializing the form (e.g. AddOrderLineItem).
5.) PROPOSAL_TEXT
The most convenient way of maintaining a many-to-one association in the client is a proposal text
field. As soon as a user enters a minimum number of characters (normally 2), only referenced
objects starting with the selected letters are shown. By entering more characters, the user can filter
down the list to better matches.
6.) FORM_LINK
In case of non-updatable associations, this component is suggested by default. The value cannot be
changed but a respective label is displayed on the form. By clicking on the label, a read-only detail
form will be opened at runtime. If no respective form exists, the action won't be performed!
Page 86
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Just like in the chapter above where we have covered many-to-one associations this component uses
a simple data transfer object containing the primary key and an optional display attribute. But in
contrast to a many-to-one association, where the form DTO contains a reference to the list DTO, the
form's DTO will now hold a collection of corresponding list DTOs.
By default, this component provides a lookup field (SEARCHABLE_LIST) in order to search for
items to be displayed in the list on the left side. A user can copy items from the left source list to the
right one by either performing a double-click action or pressing the respective selection button. The
target list on the right side contains the elements that are saved afterwards in the many-to-many
association.
If we expect only a small number of selectable items, we can change the component type to LIST.
Thereby a filter input text field will be omitted and the source list will be initialized with all objects
available!
Page 87
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 88
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Note that it is possible that the one-to-one association's target domain object also contains further
one-to-one, many-to-many and one-to-many associations. But these configurations are currently not
supported when modelling a client form.
Page 89
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 90
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 91
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
11.3.1 SIMPLE_VIEW
A form of this type provides a tabular view based on a specific domain object. Every attribute is
mapped to a separate column. Per definition, the form tries to fetch all items of a given domain
object. But for security reasons the query automatically limits the number of returned objects! It is
not possible to enter filter criteria at all.
Like single record forms, a view form always belongs to a form group. In order to create a new
form of this type, we have to choose item “Create view form”. When performing this action, an
empty dialog appears. Now, the dialog expects the selection of an existing domain object by
entering one or more letters into the auto-complete field “Domain object”. When a user presses a
key, only the domain objects starting with the selected letter are shown. As soon as we select e.g.
the Customer domain object, the form will be initialized with appropriate default values for name,
title, name of corresponding DTO and method names for searching and counting objects.
Finally, the form type SIMPLE_VIEW has to be selected in the “Form type” combobox.
Page 92
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The bottom area of the dialog contains a tab-folder with three tab-pages “Form editor”, “Select
statement“ and “Roles”. The list in group “Roles” contains the roles that may use this form and is
initialized with the roles selected in the corresponding form group.
Group “Form editor” is used to maintain table column fields. Whenever a user changes the selected
domain object or the form type, the dialog refreshes its state.
The “Domain object hierarchy” tree view contains the complete structure including all supported
attributes and associations of the selected domain object. The “Visual editor” located on the right
side of this panel contains a preview of all table column fields and default actions this form should
provide. A list view always contains only one panel that in turn holds a table. Every column of this
table is mapped to a single DTO attribute.
Additional table column fields can be added to the default table by dragging an attribute from the
“Domain object hierarchy” tree to the table of the Visual Editor on the right side. The default order
of the columns can be simply changed by dragging a table column header to the desired position.
We can also edit table column data by performing a click on the respective table column header
field.
Beside of the field's name and title, we are able to change the name of the DTO attribute and the
default column width. Moreover, the dialog provides a checkbox in order to define the column's
visibility. If a table column field is selected to be hidden, it won't be visible but the form's DTO will
contain the corresponding attribute value.
By pressing the “Delete” button an existing table column field can be deleted!
The Visual Editor also contains a toolbar with standard actions as well as actions that have been
generated when initializing the form. The number of generated actions depends on the single record
forms of the selected domain object that have been created already. Furthermore, the plug-in adds
an action to delete an object. For every binary data field of this entity, a download action is
provided. Beside of these actions, every list form contains (depending on the client technology)
standard actions to export data into Excel format, refresh the view by reloading data from the
database or application server and an action to stop a running fetch operation. Moreover, the form
provides an action to create a deep copy of a selected object. While standard actions are only
displayed for conformity reasons the generated actions may be adapted by the user by pressing the
corresponding toolbar item.
Page 93
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
This dialog can also be used to delete the currently selected action!
The tab-page “Select statement” contains a text field that displays the generated JPA select
statement which will be refreshed any time we add or remove a table column field. In text field
“Additional statement” we may enter additional static filter criteria.
Page 94
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Every time when we add a new list view to our application JBizMo automatically adds a reference
to that form to the navigator view of the application. Thus, the navigator view provides an entry
point for the user to find existing views he is allowed to open. The view's hierarchy follows the
form group structure we have already defined. In other words, every form group represents a folder
in the navigator and depending on the view's form group, the view is added to the respective folder.
The following picture shows how a typical LOV for the Person object may look like:
The selected object is returned to the corresponding LOV field by pressing the "OK" button or
performing a double-click on the respective grid row.
11.3.3 SEARCHABLE_VIEW
A SEACHABLE_VIEW is very similar to a SIMPLE_VIEW. As the name implies, a user is able to
Page 95
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
enter filter and sorting criteria. The definition of a SEACHABLE_VIEW follows the same rules as
mentioned above. Only the dialog to edit table column fields contains two additional fields. The
developer may select a suitable LOV in the “List of values” combobox that contains all lists of
values we have already created. If the checkbox “Searchable” is not selected, it will be visible at
runtime as a column in the result grid, but a user won't be able to enter filter criteria for the given
field.
Forms of this type always provide four additional actions in contrast to a SIMPLE_VIEW:
If a user performs this action, a search dialog is opened to enter filter and sorting criteria. The dialog
contains a tab-folder with two tab-pages. The first tab-page “Filter settings” is used to insert filter
criteria for all table column fields that have been defined as searchable. Every table column field
that is related to a LOV contains an icon on the right side of each row. By clicking on this icon the
user is able to open the appropriate list of values dialog.
The “Count” button performs a count operation based on entered filter settings and opens a
message-box with the result. If a user presses the “Clear” button, the dialog will perform a reset
operation on all entered filter and sort settings. By clicking on the “Search” button the dialog checks
the input and calls the appropriate search method. Afterwards, the dialog is closed and all objects
that match the filter settings are displayed in the view form.
Page 96
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The second tab-page “Advanced settings” contains fields to select if the filter criteria are case-
sensitive and if an exact filter match is expected. Furthermore, a user may select to automatically
count all objects that this query would return. This setting is obligatory for paging through result
sets. The value of combobox “Max. fetch size” determines how many objects are returned in one
fetch operation at most!
A user may hide columns from the result grid by removing items from the “Selected fields” list.
Those items automatically appear in the “Available fields” list and may be selected again to be
visible afterwards. Moreover, a user is able to change the column order of visible fields in the
“Selected fields” list by performing respective context-menu actions (“Move up” and “Move
down”).
In order to enable sorting, a user can drag a visible table column field and drop it into the “Sorting”
list. The default sort order (ascending) may be changed by performing the “Invert sort order”
Page 97
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
context-menu action.
Some kinds of queries have to be performed on a regular basis and can be saved locally by
performing this action.
When executed, the user just has to insert a unique name for the query that should be saved. As
soon as the operation is finished successfully, a new item in the navigator view's “User defined
queries” folder will appear.
In some situations, queries might return a great number of objects. To avoid long response times
and problems with the client's heap space the framework supports result set paging. That means that
a query returns always just a limited number (a page) of objects in one single step. The “Next page”
and “Previous page” actions can be used in order to navigate through all pages of the result set.
Note that the “Count records” checkbox in the search input dialog must be selected to enable this
functionality! The page size is limited by the selected value of the “Max. fetch size” combobox in
the same dialog.
Page 98
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The dialog to update Person data and to maintain the Address objects illustrates the following
picture:
Page 99
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 100
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The tree view's definition hierarchy contains various folders that a developer has to fill with desired
attributes or associations for the tree view on the left side:
We might want to easily filter the objects to be displayed in the tree view. In order to achieve that,
we just drag the name attribute of Person and drop it in this folder. Note that JBizMo supports
attributes of type String for this feature only. Every quick search item is mapped to a search input
Page 101
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The root tree item represents the first item hierarchy level grouping folders that belong together.
Direct mapping of attributes or associations to this folder is disallowed! For example, every
Person object corresponds to a root tree item.
• Display attributes
For every hierarchy level in a tree view at least one display attribute must be defined in order to
specify the tree item's label at runtime. Note that the term display attribute in this context has
nothing to do with the “display attribute” property of a domain attribute! Nevertheless, the name
attribute is a good candidate for the tree item's label.
• Tree nodes
Every hierarchy level may contain a random number of sub-nodes, whereby every tree node is
mapped to a domain attribute. Although it is not mandatory to have at least one tree node, we select
the email attribute for demonstration purpose.
• Invisible attributes
While building the tree view structure we implicitly define at least one DTO that holds all attributes
to exchange data between different application layers. Per definition, every DTO needs an attribute
that represents the primary key of the corresponding domain object. So far, the implicitly attached
tree DTO doesn't contain the primary key attribute. In particular, when working with surrogate keys,
most of the time they shouldn't be visible at all. For such cases, an attribute can be dropped to the
“Invisible attributes folder”.
• Sub-tree items
The sub-tree items folder represents a container for all items in the next hierarchy level. In order to
create a sub-tree item, we simply have to drag a one-to-many or many-to-many association from the
domain object tree view and drop it into that folder. In our first example it is possible to create just
one sub-tree item by using the addresses association. As soon as the drop operation has been
finished, a respective sub-tree item is displayed in the hierarchy tree view. Every sub-tree item, in
turn, contains folders for tree nodes, display attributes, invisible attributes and sub-tree items.
Hence, it is possible building trees with an unlimited number of levels! Note that the sub-tree items
container may contain a random number of sub-tree items.
Page 102
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The next pictures illustrate the Person tree view at design time and runtime:
In a second example, we want to discover some more advanced features of JBizMo regarding tree
views.
The application should provide a ProductHierarchy that contains a one-to-many association to
itself. This structure is always an excellent starting point in order to build multi-level tree views.
The reverse side of the association (in this case parentHierarchy) should be marked as nullable
as we need one root item at least that hasn't a parent. As the name already implies, a
ProductHierarchy contains a random number of products that in turn provide product revisions.
Page 103
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
When opening the dialog to create a new tree view, we can select the ProductHierarchy entity
as root object of the tree. Now, we are able to add products as a sub-item container of the root item.
A level below we might want to add revisions and salesCountries.
In case of multi-level tree views that contain any number of sub-levels (e.g. product hierarchies), we
might want to define quick and advanced search items. This is possible, but keep in mind that these
fields always cover the first level of the hierarchy only!
In the case of one-to-many and many-to-many associations, the generated tree views even support
drag-and-drop of sub-item elements. In our example, it is possible to change the level of a hierarchy
element and the hierarchy a product belongs to. Note that the reverse side of a corresponding one-
to-many association must be updatable in order to activate this feature when creating the tree view's
source code!
Page 104
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
By pressing the "OK" button all selected forms are being generated and the dialog is closed.
Afterwards, the selected form group in the project navigator is refreshed and contains the newly
Page 105
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
created forms.
Page 106
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
By pressing the "OK" button JBizMo creates a new boundary bean, provided that another boundary
doesn't already exist that refers to the same domain object that has been selected in the dialog.
If the creation of the new object has been finished successfully, a new dialog is opened that allows
us to add existing repository methods to the newly created boundary bean.
Page 107
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The dialog consists of two list components. While the list component on the left side contains all
available repository methods, the component on the right side shows all existing boundary methods.
A new boundary method is added by simply dragging a repository method to the list component on
the right side.
It might be the case that JBizMo needs further information if a repository method is selected. If so,
a dialog is opened that lets the user fill in the necessary data.
In some situations, the dialog is missing either necessary return or parameter types as a proper data
transfer object is missing. If so, the creation of the boundary method cannot be finished
successfully. To circumvent this, it is necessary to create a suitable data transfer object manually
and adding the desired method afterwards.
After a new boundary method has been created it is not possible to change method-related data! If
necessary (e.g. an existing method should return a different DTO), the method must be deleted in
the project navigator. Afterwards, a new boundary method with the correct settings can be created
again.
If we choose to create a DTO that shouldn't use standard conversion, all many-to-many associations
Page 108
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The context-menu of a DTO attribute also offers an item that allows us to rename the selected
attribute.
In case of standard conversion, a DTO might have attributes that in turn have a DTO type. To
achieve that, a domain association must be used for adding a new attribute. In contrast to attributes
that have a simple type, it is necessary to select the type of the new attribute in a small dialog.
Page 109
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
13 Data exchange
In most enterprise applications it is necessary to import and export data from/to external
applications (e.g. ERP or CRM systems) in a predefined manner. Since version 1.5, JBizMo is able
to support an application developer to define and generate respective services with versatile options
and features.
13.1 Basics
Before going into details, the most important terms should be described in order to ease
understanding how JBizMo works.
• Mapping object
Data is not directly read or written from external data structures into the application's
domain objects. Rather, a mapping object is used to carry data for import or export. The
generator will treat a mapping object as a simple POJO!
It would be seductive to define an architecture without such POJOs. Rather, some might
think of using persistent domain objects directly as mapping targets. From a memory
management perspective, this has some advantages compared to separate mapping objects.
Page 110
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
But using mapping objects brings more flexibility and a higher degree of abstraction. The
generator places the mapping objects into respective packages of the DTO artifact. This
facilitates their reuse in other artifacts (e.g see chapter 14).
• Mapping attribute
A mapping object contains any number of mapping attributes. Normally, the mapping
attribute represents atomic information provided by an external data structure (e.g. column
in an Excel sheet or an element in a XML file). In most cases, a mapping attribute references
a persistent domain attribute.
1.) XML
XML is still used frequently especially when different systems are exchanging data directly
without user interaction. JBizMo uses JAXB 2.0 for XML data binding.
3.) CSV
Especially in case of communication with legacy applications this format is used. JBizMo
delegates parsing and writing of CSV content to the Apache Commons CSV library.
4.) JSON
JSON (JavaScript Object Notation) is a lightweight, readable format for structuring data.
Internally, JBizMo uses JSON-B for binding objects to JSON documents.
Page 111
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
13.3 Architecture
From a system architecture perspective, a data exchange service is part of the integration layer.
Hence, it cannot be used directly by remote services or applications. Rather, boundaries/facades and
JMS queues/topics are responsible for building a bridge to remote systems. In many cases, a data
exchange service will share files directly with a file server.
Page 112
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 113
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
First, we must select an existing, non-abstract domain object that should be used in field „Select
domain object“. After a domain object is selected, the dialog will be pre-initialized. The checkbox
field „Process single object“ controls if exactly one or any number of objects should be processed
within one method invocation.
The combobox „Method type“ is responsible for selecting if we want to import or export data.
Another important field is „Content type“. As mentioned above, JBizMo supports five different
content types: XML, EXCEL97, EXCEL2007, CSV and JSON. Once defined, the content type for a
given method cannot be changed afterwards! We will come back to special features and limitations
regarding the content type in subsequent chapters. The next field „Method name“ will be initialized
when selecting a domain object with a reasonable default value. An application designer may
change the default name but the name must apply to general Java method naming rules.
In some situations, the character set must be defined when exchanging data between two systems.
The default character set is UTF-8 but it can be changed in field „Character set“. Note that the
specific target platform must support a specific charset. Otherwise, it is likely that content cannot be
processed at runtime!
The checkbox „Perform validation“ controls if the method should process data validation when
parsing or writing data. Field „Format output“ controls if output should be created in a human
Page 114
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
readable format when performing either XML or JSON data export operations.
The combobox „Joined method“ will be discussed later. If the content type XML is selected, it is
possible to define the name of a corresponding XML schema file in field “Schema file”. By
selecting the checkbox “Add to boundary” the plug-in automatically creates a suitable boundary
method that in turn invokes the data exchange method. This field is not being displayed if the data
exchange method is already used by a boundary method!
For data exchange operations using content type CSV it is possible to define various format settings
in tab-page „Format settings“.
The next tab-page „Exchange mode“ controls how content is physically exchanged between the
application and an external system. For most content types there are two modes available.
For import operations using exchange mode STRING a parameter that contains the data to be
imported will be added to the method's signature.
In case of export operations, the method returns a String if the exchange mode STRING was
selected.
The second supported exchange mode is FILE. Note that the number of fields presented to the user
depends on selected content and method type!
Page 115
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
If the method should be used for data import, the field “Path” contains the fully qualified path name
of the file to be imported. It is also possible to specify a source folder. In this case, the import
method would pick up all files in this folder.
The field „File name pattern“ contains either the import file name or a specific pattern.
Sometimes it makes sense to handle every single file in a separate transaction. If field „Start new
transaction per file“ is set, the generator will adapt transaction handling accordingly! If the target
file to be imported should be controlled by the caller of the method, we can set field „Add
parameter for path“. In this case, JBizMo adds another parameter (of type String) to the method
that contains the path of the file to be imported.
If a method should export data, we can limit the number of objects to be processed in field
„Maximum no. of objects to be processed“. Note that this field has no effect if we want to export
one object only (see field „Process single object“)!
It might be the case that an application contains a big amount of objects that should be exported.
Instead of creating one big file that the target system isn't able to parse, it is possible to split files
after a given number of objects have been processed. This can be defined in field „File block size“.
After reaching the respective threshold, the export method creates a new file and writes the next
data block to it. In this case, it is necessary to have a deeper look at the field „File name pattern“.
JBizMo is able to process static file names but like in the scenario above the generator must be also
aware of dynamic file names.
Currently, the generator supports three different dynamic file name patterns:
1.) date
If the file name should contain a date value, the pattern date should be used.
e.g. Customer_{date(now, dd-MM-yy)}.xml
The pattern expects „now“ as the value which represents the current system date. The format
string must follow the rules of class SimpleDateFormat!
2.) batchindex
If the export operation creates multiple files (see field „File block size“), this pattern helps to
create unique file names.
e.g. Customer_{batchindex(000)}.xml
The pattern doesn't need a value and the format string must follow the rules of class
Page 116
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
3.) attr
This pattern is only supported for data export operations that handle a single object!
e.g. Customer_{attr(code)}.xml
The format string can be omitted if the attribute is of type String!
JBizMo supports concatenating more than one pattern within one statement.
For export operations, it is possible to select checkbox „Return path of generated file“. If selected,
JBizMo will add a String return type to the method's signature. At runtime, the method returns the
fully qualified path name of the generated export file.
When selecting XML, the exchange mode combobox contains another item: DIRECT. If this item is
selected, JBizMo will use corresponding mapping objects for parameter or return types. In case of
an import method, a typical signature looks like:
void importCustomers(CustomerRootDTO obj)
Internally, the method doesn't have to perform parsing or unmarshalling as a suitable object
structure is already available. But what is this mode for? We will see in chapter 14 that boundary
methods can be easily exposed via a supported integration technology (e.g. REST). But in contrast
to a standard boundary method, a data exchange method provides much more powerful modelling
features (as we will see in the next chapters). Of course, the usage of a data exchange method within
an integration method is not limited to the DIRECT mode, but it provides a cleaner API compared to
a data exchange method that is based on a different mode.
In tab-page „Security settings“ it is possible to enter the permission mode. If permission mode
DEDICATED_ROLES is selected, it is possible to define specific role authorizations.
Page 117
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
1.) ASYNCHRONOUS
If selected, the generator will add the annotation @Asynchronous to the method. At
runtime, the method will be invoked asynchronously in a separate transaction context. By
entering a value in field „Invocation delay (in ms)“ it is possible to delay the execution.
2.) SCHEDULED
In many cases, it is necessary that a method is not called by a client directly. Rather, an
export or import operation should be processed on a regular basis. In this mode, the
generator adds the annotation @Schedule. For all annotation elements the form provides
corresponding input fields. Note that the application developer is responsible for entering
correct values!
Last but not least, the dialog provides a tab-page that allows us to change the default comment.
Tab-page "Comment"
Page 118
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
If a method handles multiple objects that must be either imported or exported in XML format, an
element (e.g. customers) without attributes will be added automatically. This element represents the
XML root element that always contains one sub-element (e.g. customer) that in turn carries further
sub-elements and attributes.
In most cases, it is irrelevant how many attributes are mapped to a mapping element (e.g. customer)
that acts as a container for further mapping elements or attributes. Normally, it is necessary that a
corresponding primary key or display attribute will be mapped to a container-element! Otherwise, it
can be hard or even impossible for the generator to create proper output! If the external data
structure cannot provide either the primary key or the display attribute, it is also possible to create a
valid mapping. But this will be discussed in one of the following chapters.
To some extent, the external data structure must match the domain object model. That means that a
persistent attribute cannot be placed at any location in the mapping tree view. A persistent attribute
can be added to a container-element if the attribute belongs directly to the attribute list of the
container-element's domain object. It is also possible that a domain attribute will be mapped if it is
connected through any number of cascaded many-to-one or one-to-one associations to the
container-element's domain object! JBizMo prevents creating illegal or unsupported mappings!
In a first step, we just map some persistent domain attributes to a XML data structure by dragging
attributes from the domain object tree view and add them to the “Attributes” folder of the container-
element customer.
Page 119
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Note that it is also supported to map domain attributes to XML elements! In this case, we just would
have dragged the domain attributes to sub-folder “Elements” of container-element customer!
If another content type is selected, the mapping file structure will look differently:
Page 120
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Depending on specified format settings (see above), a corresponding CSV data structure could be
like this:
"Id";"Name";"Credit limit";"Customer status"
"123";"ABCD Inc.";"0.00";"NEW"
In some scenarios, it is not possible that an external system either provides the primary key or the
display attribute of our domain model in order to determine the respective association when
importing data. To handle these cases JBizMo provides another way of reference control. The dialog
to create new data exchange methods contains another tree view component in the „Mapping“ tab-
Page 121
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
page that can be used to overwrite default association control. In almost the same manner as
attributes can be mapped to an external data structure a mapping attribute from the mapping tree
view or an association from the domain object tree view can be dropped to this component. After
this operation has been finished, a new item will be added. The root node contains information
about the association being used and contains two sub-folders.
The sub-folder “Attributes for reference determination” contains all attributes that should be used to
control the association.
Reference control
If an association is configured to be driven by these attributes, the generator won't use a mapped
primary key or display attribute for reference determination. Note that the generator requires one
mapping attribute to be defined at least in order to generate expected output!
It is even possible to create referenced objects that currently don't exist in the project's target
database we are importing data to. In order to instruct the generator to handle that case, we can drag
mapping attributes to folder “Attributes for creation of missing references”.
As an example, it should be assumed that the customer data import interface provides an attribute
that is mapped to domain attribute name of domain object CustomerGroup. Moreover, it could be
the case that the interface provides attribute values that don't exist in the database yet and the import
process should create missing reference objects of type CustomerGroup. The mapping attribute
customerGroupName must be added to both folders:
The generator will add a new method (e.g. findCustomerGroup()) for all associations that
should be handled in that way. First, the method will perform a query in order to search for an
object that fits expected filter criteria (e.g. customerGroupName).
If the query finds an object, it will be returned directly to the data import method. In the case of
getting non-unique results, an exception will be thrown! If no object has been found, it will create a
new CustomerGroup object, sets all available attributes that have been specified in folder
“Attributes for creation of missing references”, persists the new object and finally returns it to the
caller.
Page 122
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Mapping of a many-to-many
association (XML)
If the method should either import or export data in Excel format, the association must be dropped
to the root element Sheet1!
Mapping of a many-to-many
association (EXCEL)
JBizMo creates a second container-element Sheet2. We also drag the id attribute of domain object
SalesPerson to the “Attributes” folder of Sheet2.
Page 123
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Note that the plug-in automatically adds another mapping attribute JOIN_COLUMN. If the data
exchange operation should handle more than one “master” object (e.g. Customers), this column is
necessary to link “detail” objects in further sheets (e.g. Sheet2) to rows of the master sheet (e.g.
Sheet1). It is possible to delete that special mapping attribute but the generator won't be able to
generate code that is responsible for joining master and detail objects afterwards. The
JOIN_COLUMN is also used for mapping of one-to-many associations (see the following chapter).
The mapping of many-to-many and one-to-many associations is not supported for content type
CSV!
In contrast to many-to-many associations where only references between two objects had to be
maintained, we now have Customer and Contact objects that must be handled in a proper way!
Therefore, it is normally not enough just to map the primary key or display attribute of the
association's target domain object. Particularly for data import operations where Contact objects
have to be either created or updated it makes sense that an appropriate number of attributes is
mapped. JBizMo doesn't provide a check if mandatory mapping attributes are missing for insert
operations!
Page 124
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
It is also possible to handle one-to-many association mappings for Excel documents. The mapping
tree view is slightly different:
As described above, it is allowed to map all attributes that are directly or indirectly wired through
many-to-one or one-to-one associations to a container-element's domain object. For this reason, we
can just map all attributes of CustomerInfo to the customer element:
Page 125
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The id attribute of domain object CustomerInfo can be omitted in that case as its value is created
by the persistence provider.
As an alternative, the association can be also used to create a new container-element by simply
dragging the association from the domain object Customer to the “Elements” folder of the
container-element customer.
Furthermore, we even could mix aforementioned mapping strategies! But care has to be taken as the
generator is not optimized for that and thus, runtime errors might come up due to association
cascade settings that prevent the referenced object (e.g. CustomerInfo) from being persisted!
Note that mapping of associations to container-elements is generally not supported for CSV!
Page 126
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 127
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The field “Name” contains the name of the mapping attribute. The mapping attribute's type name is
shown in field “Mapping type” and cannot be changed! The field “Attribute order” is empty by
default. A value can be entered but the plug-in won't use the field value in the current version!
An external data structure may contain optional attribute or column values. The checkbox
“Optional” can be used to overwrite the default setting. Normally, an attribute or a column that
belongs to the external data structure is mapped to a mapping attribute that in turn belongs to a
mapping POJO. The field “Mapping attribute name” can be used to change it.
Especially for CSV content, the field “Format” is used in conjunction with numeric and date
attributes. This is necessary because of the fact that all cell values that must be read come as
String. The generator must be aware of how to convert these values into appropriate target types
(e.g. java.util.Date)!
In case of data import operations, it is possible to control if an attribute should be used for insert
and/or update operations. The fields “Insertable” and “Updateable” allow the user to overwrite the
default values.
Sometimes the business logic requires limiting the number of possible entries in a field. Those
business rules can be even expanded to external data structures! For example, a String field
Page 128
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
should contain only the values “UNDEFINED” and “ACTIVE”. These values can be added to list
component “Value list entries”. For the supported content types the effect of doing so is different!
For XML the values would be added to the respective XML schema. In case of EXCEL97 or
EXCEL2007, the generated export file would be supplied with a list constraint for all cells of a
particular column. For CSV and JSON these entries have no effect!
In some cases, the external data structure is not able to provide mandatory data for a given attribute.
As a result, import operations would fail due to the fact that an object cannot be created with
missing mandatory fields. To solve that problem an attribute can be provided with a default value in
field “Default value” and field “Disable mapping to external data structure” can be selected!
For data exchange methods that collaborate with EXCEL97 or EXCEL2007 files the dialog looks
slightly different as it contains some additional fields:
The field “Visible” controls if a column is visible within a respective sheet. This can be helpful
when exporting e.g. surrogate keys that should be available in the sheet but not visible to an end
user. The value of field “Readonly” has currently no effect.
JBizMo also provides a powerful feature that allows adding selection lists to generated Excel files
for a given attribute. We just have to enter a valid JPA single-attribute query statement (see above)
into the field “Selection list statement”. Note that it lies in the developer's responsibility to enter a
formal correct statement!
If an attribute contains a selection list statement and entries in field “Value list entries”, the plug-in
will automatically use the list statement prior to the value list entries when generating the method's
source code!
Page 129
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
It was already mentioned that we normally need either the primary key or the display attribute in
order to determine the respective domain object at runtime. But sometimes an external data
structure cannot provide this data. In this case, we can select one or more attributes that should be
used for searching a root domain object by selecting field “Use for customer queries to search for
root domain objects”. If selected, the generator will add an additional method to the generated
exchange service bean that will be responsible for searching the root domain object while
performing a data import operation.
The fields “Min. occurrences” and “Max. occurrences” control how often an element may appear
within a parent container-element. For domain attributes the value for “Max. occurrences” is always
1 and cannot be changed. The possible values in field “Min. occurrences” are 0 or 1. The field
“Element order” is intended for future use!
Page 130
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The field “Name” contains the element's name. In field “Mapping type” we can change the default
name of the corresponding mapping object class. The fields “Min. occurrences” and “Max.
occurrences” define how often the respective element can be added to its parent element. For root
container-elements both fields always have value 1! Values in field “Element order” currently have
no effect! In case of data import operations, the dialog contains three additional fields that manage
general generator characteristics. If field “Create new items” is selected, the generator will add
source code in order to create non-existing objects. It is also possible to control if fields of existing
objects should be updated during the import process. If “Update existing items” isn't selected, the
import won't touch existing objects at all! Note that it is even possible to deselect both fields. In this
case, the import neither creates new nor it updates existing objects. Care has to be taken if field
“Delete all existing items” will be selected! In this case, the import would delete all objects (e.g.
customers) before creating new objects provided by the import interface.
If content type XML is selected, the dialog will contain an additional field “Schema type name” that
allows the developer to change the initial name of the XML schema type.
If we want to perform a XML data exchange operation with Customer objects including the one-to-
many association contacts, the corresponding container-element's dialog will contain another
field “Wrapper element name”. As soon as we enter a field value (e.g. contacts), the contact
elements will be embedded into the parent element contacts!
Page 131
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
<customers>
<customer id="123" name="ABCD Inc." customerStatus="NEW" creditLimit="0.0">
<contacts>
<contact id=”642” firstName=”Jane” lastName=”Doe” phoneNumber=”112”.../>
<contact id=”142” firstName=”John” lastName=”Doe” phoneNumber=”110”.../>
</contacts>
</customer>
</customers>
In a first example, the external data structure should provide a XML attribute, a CSV or an Excel
column or a JSON name-value pair with name type and the import process should be able to import
that into the mapping attribute customerType. An unmapped attribute can be added by clicking on
pop-up menu item “Add attribute” of sub-folder “Attributes". The following dialog will be opened:
When performing the import operation, the respective method is now able to read data from the
attribute type and would write the value into mapping attribute customerType. Note that the
field's value cannot be written to the target database as no persistent attribute exists that is able to
carry it! It is now up to the developer deciding how to continue working with that unmapped
Page 132
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
attribute.
If no value has been entered in field “Mapping attribute name”, an attribute won't be added to the
respective mapping object (e.g. CustomerExchangeDTO)!
If the application should export customer objects to an external system, it is also possible that we
define unmapped attributes. Particularly in these cases it might be helpful to enter a default value
(e.g. N/A) for mandatory attributes of the external data structure!
For content type XML JBizMo provides the functionality to create unmapped elements. The pop-up
menu of sub-folder “Elements” contains two items. If we select menu item “Add unmapped
element”, the following dialog will be opened:
The dialog requires entering values into fields “Name” and “Mapping type”. By pressing “OK”, we
extend the XML schema with an element that belongs to a respective parent element. A mapping
attribute to be filled by the parser won't be added!
If such a mapping attribute is required, the menu item “Add mapped element” has to be selected! In
this context the word mapped refers to the corresponding mapping attribute!
Page 133
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The field “Generated select statement” contains the query statement created and maintained by
JBizMo. It shouldn't be changed manually! As an example, the method should only export
customers with a credit limit greater than 0. The appropriate JPA query fragment can be entered in
field “Additional statement”.
The grid component provides a context-menu with different items to create, update and delete filter
parameters. By clicking on item “Create new parameter” a dialog is opened:
When creating a new parameter, the dialog expects a valid name in field “Name”. Furthermore, an
operator must be selected. The combobox “Domain association” contains all many-to-one and one-
to-one associations of the selected root domain object (e.g. Customer). As soon as we change the
selection, all domain attributes of the selected association's target domain object will be added to
combobox “Domain attribute”! If no association has been selected, the combobox will contain all
attributes of the root domain object. Note that every filter parameter requires an attribute to be
selected! When pressing "OK", the parameter will be added to the method:
String performCustomerXMLExport(CustomerStatus customerStatus)
The generated JPA query statement (see above) will be adapted also:
select a from Customer a where a.customerStatus = :customerStatus
It is possible to add any number of filter method parameters. The generated query fragments will be
concatenated using an AND operator!
Page 134
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
As soon as a data exchange method is used by a boundary method it is not possible to either add
new or delete existing filter parameters.
Whenever the developer changes these settings, the dialog searches for suitable import methods and
adds them to combobox “Joined method”.
Page 135
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
As soon as we select a method in combobox “Joined method”, the tree view components in tab-
page “Mapping” will be reseted and disabled as mapping definition is entirely driven by the import
method.
As soon as an exchange method in combobox “Exchange method” is selected, all dialog fields will
be initialized automatically with proper default values. When pressing "OK", a new action will be
added to the corresponding view form. Moreover, the plug-in creates a boundary/facade method that
in turn forwards invocations to the selected data exchange method.
Page 136
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
14 Integration beans
The previous chapters have already documented that JBizMo also provides a feature for modelling
integration beans. In this chapter, we want to discuss the details of how this is implemented.
14.1 Basics
In the current version, JBizMo supports five different integration technologies. SOAP, REST, JMS
and RMI can be used in a Jakarta EE project. The integration technologies SOAP, REST, JMS and
Kafka are supported in Spring Boot projects. It is also important to note, that a respective
integration module must have been defined while creating a new project (see chapter 6). The
definition of new integration modules after creating a new project is not supported!
A new integration bean can be created by selecting the respective integration module namespace in
the project navigator. When selecting the context-menu “New integration bean”, a dialog for
creating the new service is opened. The integration technology is implicitly defined by the
integration module namespace we have selected before!
The starting point for initializing a new service always represents the selection of an existing
domain object by using field “Domain object”. As soon as a valid domain object is selected all other
dialog fields are filled with appropriate default values.
The name of the service implementation class can be changed in field “Bean name”. The field
“Interface name” represents the name of the service endpoint interface. If the integration module
provides a client artifact, the field “Client class name” can be used to change the default name of
the generated service client class. If the field is left blank, the generator won't create a respective
class! If the the creation of producer classes is enabled for the given integration module the dialog
will contain a field “Producer class name” that is filled with an appropriate default value. As with
the “Client class name” field it is possible to provide an empty input so that this class won't be
created.
It is important to understand that integration bean methods always refer to a corresponding
boundary method. Initially, an integration bean hasn't got a method. The definition of new methods
is accomplished in the main area of the dialog which contains two tree views. The tree view on the
left side is responsible for displaying all available methods that can be used for adding a new
method to the selected bean. If a domain object is selected, this tree view will contain all existing
boundary and repository methods. Thus, it is even possible to select a repository method. In this
case, JBizMo will create a respective boundary method internally that in turn is referenced by the
corresponding integration method. The tree view on the right-hand side shows all existing methods.
We can create a new integration method by dragging an existing boundary or repository method to
the tree view on the right-hand side.
In the case of an Angular application JBizMo will automatically create all REST integration
methods that are necessary for the communication between the GUI and the back-end!
We will see in the following chapters that JBizMo provides comprehensive support for controlling
technology-related information on bean and method level. But this does not apply for method
parameters! If necessary, the respective source code generators will use reasonable default values
(e.g. regarding annotations) in order to supply further information regarding integration method
parameters.
Page 137
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
No matter what technology has been chosen, this dialog has always the same base structure and
provides the same functionality. On the other hand, every technology comes with its own specific
details that must be handled in order to create a service in an adequate manner. The following
chapters will show the technology-specific settings that are supported by JBizMo.
14.2 REST
When creating a REST service, the dialog will contain two additional fields. The field “Path”
controls the URI path template to which the respective resource responds. In the current version,
JBizMo supports two different content types (JSON and XML) that can be used to map an ASCII-
based character string to an arbitrary number of objects a REST method may either consume or
produce. The combobox “Default content type” controls the preferred content type when creating a
new integration method. We will see afterwards that it is also possible to change the default content
type for every single method.
After dragging a boundary method (e.g. updateCustomer) to the tree view on the right side, JBizMo
automatically creates a new integration method which in turn is instantly displayed in the
integration method tree view. When performing a double-click on the respective tree view item, a
dialog is opened that allows us to change the proposed default settings.
Page 138
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Beside of the standard fields “Name”, “Start new thread” and “Comment” that are available for
every integration method the rest of the fields depend on the selected integration technology. In case
of REST, following fields are also available:
Path URI path template to which the respective method is mapped to. The field
can be blank.
HTTP method The HTTP method the integration method is mapped to. Possible values are
PUT, POST, GET, DELETE and HEAD
Input content type Is used to specify which MIME media type or representation a resource can
accept, or consume, from the client. The possible values are JSON, XML,
TEXT and NONE if the method doesn't expect a content.
Output content type Is used to specify the MIME media type or representation a resource can
produce and send back to the client. The list of possible values is equal to the
input content type!
If the checkbox “Start new thread” is selected, the generator will build the integration method in
such a way that the respective boundary method will be invoked in a new thread in order to relieve
the HTTP thread pool of the container at runtime.
Page 139
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
14.3 SOAP
If we create a new SOAP service, the dialog will contain the following fields:
RPC style Defines the encoding style for messages sent to and from the web service. If
the checkbox is selected, the style is RPC, otherwise, it is DOCUMENT.
Bare parameter style Determines whether the method parameters represent the entire message
body or whether parameters are elements wrapped inside a top-level element
named after the operation. If the checkbox is not selected, the parameter
style WRAPPED will be applied for the given service.
Service name Specifies the service name of the web service: wsdl:service.
Port name Defines the wsdl:portName.
Port type name The name of the wsdl:portType.
Please note that the JAX-WS standard doesn't support all possible combinations of the SOAP-
specific bean settings. For example, the BARE parameter style must not be used in conjunction with
encoding style RPC!
Page 140
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The dialog for maintaining a SOAP integration method comes with four additional fields:
Operation name Specifies the name of the wsdl:operation matching this method.
Return value name Defines the name of the return value as it is listed in the WSDL file
and found in messages on the wire. For RPC bindings, this is the
name of the wsdl:part attribute representing the return value. For
document bindings, the -name parameter is the local name of the
XML element representing the return value. The default value is
return for RPC and DOCUMENT bindings. The default value is
the method name + Response for DOCUMENT bindings.
Return value part name Specifies the part name for the result of RPC or DOCUMENT
operations. The default value is @WebResult.name.
Add parameter annotations Controls if the generator adds JAX-WS annotations to method
parameters.
Page 141
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
14.4 RMI
As we can see in the following picture an RMI service doesn't contain technology-specific fields:
As with the bean dialog, an RMI integration method also doesn't provide additional fields.
Page 142
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
14.5 KAFKA
In contrast to the aforementioned technologies (e.g. REST) that follow a basic request-response
pattern, there are some notable differences if the application uses Kafka. At the latest, when the
respective beans should be tested, it is necessary to have a Kafka broker that is responsible for
saving incoming messages in respective topics.
The following picture depicts all major building blocks as well as the basic data flow:
A Kafka client sends messages to a dedicated topic. As soon as the application has been started, the
integration bean listens for messages in the same topic. If all requirements regarding the message
payload and the message headers are met, the bean is able to process the message by delegating the
actual work to the respective listener method. In JBizMo this method is responsible for converting
the message payload into one or more parameters that are used to invoke the actual boundary
method. Due to Kafka's asynchronous nature, the actual return value or a status cannot be sent back
directly. Thus, it is necessary to send an appropriate message to a response topic. This message, in
turn, can be consumed by the same client that has sent the original request message. Of course, it is
possible that other clients are listening on the same topic which are also able to consume the
message.
At the moment, JBizMo uses Avro for the serialization of the messages. Therefore, a new Avro IDL
file is added to the resource folder in the service endpoint interface artifact for every integration
bean. This file contains all data structures, enumerations, response and request schemas for all
methods of a specific bean. The following examples provide an overview about all relevant parts in
the Avro IDL file for creating a new object (e.g. a customer).
Page 143
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The record CustomerDTO contains all fields that are necessary for this operation:
/**
* Data transfer object for customer objects
*/
record CustomerDTO
{
long id;
string name;
int version;
timestamp_ms creationDate;
}
Due to JBizMo's strong coupling between the integration technology and the application, the
request schema contains at least one field for every boundary method parameter.
/**
* Request schema for "createCustomer" operations
*/
record CreateCustomerRequest
{
CustomerDTO object;
}
If a response including the return value of the boundary method invocation should be sent a
corresponding response schema is added which always contains a general response object with a
status code and an optional error message.
/**
* Response schema for "createCustomer" operations
*/
record CustomerCreateResponse
{
ResponseStatus responseStatus;
union {null, CustomerDTO} responseData = null;
}
A response message with a ResponseStatus object is sent to the respective Kafka topic if no
dedicated schema has been selected!
Internally, JBizMo generates Avro-related Java classes that are used for the serialization of the
schemas by using the Apache Avro Maven plug-in. The integration bean expects that the message
header contains the name of the Avro schema for routing the message to the correct listener method.
If a response message should be sent the original request message contains a correlation ID that in
turn is added to the response message header which allows the message sender to identify the
correct response message.
Following additional fields are necessary for creating a new Kafka integration bean:
Request topic Defines the name of the topic that is used by all service listener methods.
Response topic Defines the name of the topic where the response status and/or the
invocation result (e.g. the method return value) should be sent to after
processing a message from the request topic.
Consumer group Controls the name of the consumer group the service listener belongs to.
Page 144
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The dialog for maintaining a Kafka integration method contains following additional fields:
Request schema name Defines the name of the Avro request schema.
Send response Controls if the listener method should send a response message to the
respective response topic. If no response message should be sent the
following fields will be disabled!
Response schema name Defines the name of the Avro response schema. If this field is empty
no dedicated response schema will be added!
Use dedicated partition Controls if the client provides the partition where the listener method
should send the response message to. This feature reduces the overall
network traffic in a system where many clients are listening on the
same topic as the client just fetches the response messages of the
desired partition!
Page 145
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
After creating a new Kafka integration method, a corresponding listener method is added to the
integration bean.
Page 146
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
14.6 JMS
Another supported integration technology based on asynchronous message processing is JMS.
Depending on whether Jakarta EE or Spring Boot is used, there are two variants of the currently
supported setup. While Spring Boot applications expect a dedicated broker (Active MQ Artemis),
Jakarta EE applications work with embedded brokers.
A JMS integration bean contains a listener method that processes the request messages of a topic or
queue. This listener method expects a JMS ObjectMessage of type RequestMessage along
with a correlation ID. The RequestMessage class contains a field with the operation ID that is
used to determine what boundary method should be called. The second field represents an ordered
list with serializable objects that must match the expected list of boundary method parameters. If the
incoming message was successfully converted, the listener method calls the boundary method and,
if necessary, sends a JMS ObjectMessage of type ResponseMessage back to the corresponding
JMS destination. A ResponseMessage consists of the optional return value of the boundary
method, a response status, an optional text that represents a human-readable error message and the
operation ID of the corresponding request message. The aforementioned correlation ID is also
added to the JMS response message so that a client can easily find the corresponding response to
the request it has sent.
Page 147
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
When creating a new JMS integration bean following additional fields are necessary:
Request destination Defines the JNDI name of the destination that is used by all service
listener methods.
Response destination Defines the JNDI name of the destination where the response object
should be sent to after processing a message from the request destination.
is JMS topic Controls if the respective destination represents either a topic or a queue.
It is important to note that the JMS destinations of a Jakarta EE application must be configured
before deploying it. Otherwise, the deployment will fail!
Page 148
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The dialog for maintaining a JMS integration method just contains one additional field that controls
if the listener method should send a response message to the respective response destination.
Page 149
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
These drawbacks were the motivation to implement a simple protocol that should avoid
aforementioned problems. By default, every JBizMo rich-client uses this HTTP-based protocol in
order to communicate with the application server. Therefore, we won't run into problems with
firewalls. Furthermore, load-balancing is possible by either using appropriate software (e.g.
mod_proxy of the Apache HTTP server) or hardware.
Although the internals are quite sophisticated, the protocol is easy to use for an application
developer. In a first step, the (remote) client application must initialize a ServiceLocator object
including all necessary information to connect to a remote system (e.g. target URL and application
name).
final var hostLocal = new ServiceLocatorDTO
(
ALIAS_HOST_LOCAL,
"http://host/my-invoker",
false,
TransportType.HTTP
);
As soon as the ServiceLocator has been initialized, the application is able to use remote
boundary service interfaces. In the beginning, it might seem strange that the client application
works with interfaces only. But there are two reasons for that: On the one hand, the implementation
resides on a remote server and the method should be processed remotely. Hence, we don't
necessarily need the implementation of the boundary service. On the other hand, every call to a
boundary method must be intercepted by an InvocationHandler that is physically responsible
for remote communication. In order to facilitate proper invocations, it is necessary that the
boundary interface will be initialized via the ServiceLocator.
UserBoundaryService service = ServiceLocator.getService(UserBoundaryService.class);
When invoking the boundary method findUserById(), the InvocationHandler knows how to
convert the invocation into a generic transport object. In most cases, it sends a HTTP request to the
InvocationServlet which is responsible for acting as a controller that in turn searches for a
Page 150
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
respective boundary service (e.g. via a JNDI lookup) and performs the method invocation. Finally,
the servlet converts the invocation result or an exception into a generic transport object and sends it
back to the InvocationHandler. Afterwards, the InvocationHandler converts the result and
returns it to the client. The protocol web application also provides two further services: the
FileUploadServlet and the FileDownloadServlet. As the names imply, these servlets are
optimized for exchanging files between client and server.
When generating the rich-client application, all necessary configurations and source code is being
created by JBizMo. Most of the time an application developer just has to adapt the given target URL
in order to connect to the desired back-end system.
Page 151
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
16 GUI testing
Testing is a fundamental, yet sometimes expensive, part of the software development process.
JBizMo provides powerful features for generating tests for JSF and Vaadin web applications based
on Selenium. It is important to note, that generated tests always follow two basic design patterns.
First, a generated GUI test is data driven. That means, that anything that has a potential to change is
separated out from the test logic. By default, JBizMo will create a separate XML file for every test
case that contains test data. The other basic design pattern represents the so-called page object. A
page object simply provides all available functions of a single web page or a fragment that can be
used in a test. This reduces the amount of duplicated code and means that if the GUI changes, the
fix need only be applied in one place.
The forms that are used in the following examples are based on the domain model of chapter 13.4.
The text field “Name” is automatically filled with a default value. Note, that all test cases belong to
the same package within the GUI test artifact. Thus, every test case needs a unique name! The field
“Comment” is optional. A GUI test case contains an arbitrary number of so-called test actions. In
the following chapters, we will cover all details regarding test actions. At the beginning, the first
test case should only contain one test action that can be added to the test case in the “Add new
action” area. Usually, an existing web page must be opened in order to test its functionality. The
selection of an existing form can be done in the text field “Open form”. As soon as characters are
Page 152
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
entered, all available forms that match the entered text are displayed. Note that tree views (see
chapter 11.4) are currently not supported and won't be displayed in this list!
After selecting a form further fields of this section will be enabled. In the case of view forms, the
checkbox “by using main navigator” can be selected. If this field is selected the respective form is
opened by using the main navigator component of our application. Otherwise, the form is opened
directly! Forms that display data for an existing object (e.g UPDATE, READONLY) cannot be
opened if the ID of the respective object is missing. Thus, it is necessary to enter that value into the
field “with object ID”. For our first test, we select the form CountryView. A value for the object ID
is not necessary. By pressing the “Add” button a graphical editor that represents the selected view is
opened.
The graphical editor provides two fundamental features. First, it automatically creates further test
actions by recording user interaction. For example, when clicking on a tool-bar item (e.g. 'Refresh')
the corresponding test action will be added and the user gets notified by a respective text in the title
area of the preview dialog. The second key feature of the graphical editor represents entering of test
data. For our first test, we neither add further test actions, nor we must enter test data as we just
want to test if the view can be opened. Hence, we save that test action by clicking the "OK" button
and the graphical editor will be closed.
The initially empty section 'Existing test actions' displays our first test action as depicted in the
following picture.
Page 153
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Let's save the first test case by clicking on the dialog's "OK" button. Thereby, the dialog will be
closed and JBizMo creates the test case file in the GUI testing artifact of our workspace. This
artifact also contains a resource folder where all test data files are saved to. Although our simple test
doesn't require test data a respective file should have been created also! If everything worked fine
the new test case should be visible in the “Selenium” folder of the project navigator.
Many features regarding GUI testing are provided by a special JBizMo runtime library. For
example, our class NewTest is derived from AbstractSeleniumTest. The tasks of this class are
Page 154
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
The class SeleniumTestContext also belongs to the JBizMo runtime library and it is used for
the initialization of page objects (e.g. CountryView) regarding configuration properties and the
Selenium WebDriver. Furthermore, it is responsible for loading test data.
Every generated test case contains only one test method that is invoked as soon as the initialization
of a SeleniumTestContext instance has been finished and the test environment is ready. The
method now executes every single GUI test action in the predefined order.
The aforementioned Selenium runtime library is tightly bound to the functionality of an application
that has been created by JBizMo. Thus, it doesn't raise the claim to represent the leading Selenium
library for all other JSF and Vaadin applications out there!
/**
* Constructor
* @param testContext
*/
@Generated
public CreateNewCountryDialog(SeleniumTestContext testContext)
{
super(testContext);
}
}
The most important characteristic of a page object is the fact that it extends the runtime library class
AbstractPageObject that provides all necessary functionality for interacting with the web page
at runtime. Furthermore, it contains constants for all visible form fields. Normally, these objects
don't have state. Only if a form contains either grid panels or list fields a corresponding property is
added to the page object's class.
As a page object class is tightly bound to a corresponding form JBizMo will automatically
synchronize the page object as soon as the respective form has been changed! When deleting a form
the page object is also deleted!
Page 155
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Element Description
test_case The element test_case represents the root element of the XML file.
test_action JBizMo will create one test_action element for every test action that needs test data.
Attribute Description
pageClassName Contains the fully qualified name of the page object class
this test action refers to. At runtime a test data provider
collects all test_action elements of the same page object
and will return these elements in the order as they have
been defined in the XML file.
objectId This attribute is filled with an appropriate value if a page
for an existing object must be opened.
navigationTarget If a page is opened using the application's main navigator
this attribute contains a value for finding the proper item in
the navigator tree view structure.
element For every HTML element that should be either changed or tested a separate element
tag is added to the test_action. It could be the case that this tag doesn't refer to a
HTML element as this tag is also used to store test data for specific test actions (e.g.
page title tests, row count validation and row search operations).
Attribute Description
id The attribute usually contains the ID of a HTML element
that should be either modified or tested. It is also possible
that it contains internally used IDs for page title tests, row
count validation and row search operations (see chapter
16.6 and following).
filterValue If a HTML form element is used to search data the filter
value is entered in this attribute.
newValue The newValue attribute contains the text that should be used
to change a corresponding HTML element.
expectedValue This attribute contains the expected value of a HTML
element that is defined by the id attribute.
result In chapter 16.7.3 we will see that it is also possible to test status messages that are
Page 156
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
shown to the user after performing a web page action. The result element is
responsible for providing respective data.
Attribute Description
status Represents the expected status of a message component
(e.g. INFO, WARNING, ERROR).
message Contains the expected message text.
Of course, it is possible to change the content of the file manually. But these changes get lost as
soon as JBizMo rebuilds the test case this file belongs to.
Page 157
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 158
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
As a new customer should be created in this test case it is necessary to enter data into respective
fields of the graphical editor. It is important to note that the entered field values are used exactly as
they have been entered. This means that the format of date and numeric values (e.g. Credit limit)
must match the corresponding settings in the web application. Furthermore, it is very likely that a
test will fail if the value of a lookup field (e.g. Customer group) doesn't exist in the application's
database. The developer is also responsible for entering all mandatory fields. If a mandatory field is
left blank it is possible that the test will also fail! The graphical editor changes the background
colour for every non read-only input field into yellow as soon as the user enters a text.
When pressing the "OK" button the new test action will be added to the test case and the graphical
editor is closed. Beside of the test action for entering form data an additional test action for pressing
the form's "OK" button will be created automatically.
The new test actions including all details (e.g. test data) should now be visible in the test case dialog
as depicted in the following picture.
Page 159
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
After successfully executing the test for the first time everything seems to be fine! Running the test
again will definitely fail as the test tries to create a customer with a name (here TESTCUSTOMER)
that already exists. The root cause of the problem is that the corresponding column possesses a
unique key constraint. It is always a good strategy that a test discards all changes being made in the
database before the test is about to be finished. In this case, the problem can be avoided by creating
an additional test action that deletes the customer at the end of the test (see chapter 16.6.3).
Page 160
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
If values of form fields should be changed and tested within one test action the validation will be
always performed prior to setting a new field value!
If we come back to chapter 16.1 where we have defined a simple test action for opening a view that
displays all countries we might want to open the form to update an existing country for changing
some field values. In order to define the row that represents the country that should be changed
there are three options available. A row can be searched by using
• a cell value
In this case, the test will search for a row that contains a visible cell with the given value.
The developer is responsible for providing a value that sufficiently identifies the row in
order to avoid selecting a wrong one.
• a row index
When selecting this option the test will search for a visible row at the given index. Per
definition, the first row has index 1!
• the object ID
We have already learned that every persistent domain object has a primary key attribute. If
this option is selected the test will search for a row with the respective value. It is allowed
that the respective column is invisible! Note that this mode is not supported for Vaadin
applications!
By default, the search operation does only include the initially loaded rows. If the test should use
the table's pagination feature it is also possible to select “enable searching row in all available
pages”. It is seductive to enable this option always! But keep in mind that it can dramatically
Page 161
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
increase the test time! If the test is not able to find a row the test will fail!
Normally, a form action is triggered using the table's context-menu. It is also possible to execute a
form action by performing a double-click on the given row. The respective option is only enabled if
a double-click for the respective form action is basically supported!
Due to the fact that a double-click might open different forms depending on the user that is logged
in, it is possible to overwrite the default value in combobox “Target form”.
If we want to create a new country object we can simply click on the respective tool-bar button of
the view form. In this case, the row selection dialog is not opened as no selection is necessary.
Rather, the graphical editor for creating a new country object is opened directly! As this example
illustrates, it's possible to create very complex test flows as one test action can be the starting point
for many others. In other words, a graphical editor dialog may open an arbitrary number of other
graphical editor dialogs. JBizMo is responsible for recording the user interaction and adding new
test actions to the test case in the correct order.
Some test actions (e.g. executing a data exchange operation see chapter 13 and following) neither
require the selection of a row nor open a target form. In this case, only a notification in the title area
of the graphical editor is shown indicating that a new test action has been added.
Beside of entering filter criteria it is also possible to select a filter operator and the sort order for a
specific column. By pressing the dialog's "OK" button a search input operation will be added to the
test case. After opening the form at runtime the provided test data will be used accordingly and the
view should be filled with the expected results. By using this dialog it should be relatively easy to
Page 162
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
force the application returning only the row we are interested in!
Alternatively, the dialog can also be used to perform either a count or an input reset operation by
pressing the corresponding button!
The selection of the operator combobox controls if the number of expected rows is either greater,
smaller or equal compared to the value entered in the dialog's text field. By pressing the "OK"
button the new test action is added to the test case.
Page 163
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
After clicking the "OK" button a new login test action is created.
The aforementioned context-menu also contains an item “Add logout action”. If this item is selected
a new logout test action will be added to the list of existing test actions.
Page 164
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
After selecting the checkbox on the left side of the dialog the rest of the dialog components will be
enabled. The combobox on the right side controls if the test action will either open a dialog or a
notification message. For Vaadin applications only the option DIALOG is available! The text field
in the next line can be used o enter an expected message that the selected component will present to
the user. Depending on the severity of the failure the message component has a different status. The
supported states are INFO, WARNING and ERROR!
As this functionality assumes that an error can be handled by the page using a notification
component it cannot cover situations regarding unexpected errors that might open the standard error
page!
It is possible to remove an existing result check from a test action by opening the dialog again. After
unselecting the checkbox and pressing the "OK" button the result check will be removed.
Page 165
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
By pressing the “OK” button the changed text will be saved and the respective files are being
rebuilt.
Page 166
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
A valid name must be entered into field “Name”. The comment field is optional. It must be
considered that all test case and test suite classes belong to the same package. Thus, the name must
not match the name of an existing test case or test suite!
Test cases that should be added to the test suite have to be moved from the list of available test
cases on the left side of the dialog to the list on the right side. The order of the selected test cases in
the list also controls the execution order when running the test suite. The rule is that the topmost test
case in the list is executed first.
Page 167
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
If the application accesses the target database directly (without using an application server), we will
only have to take care of synchronizing the target database with our domain model!
In order to successfully run a client application that communicates with an application server, there
are some prerequisites that must be met:
• The target database needs to be in sync with the application's JPA entities.
• The application server must have been started.
• The web application archive (crm.war) must be successfully deployed on the application
server.
A Jakarta EE application can be easily deployed by performing the Apache Maven build command
“clean install”. This command automatically deploys the application to the selected application
server.
In case of RCP applications, we have to open the product definition file (application.product) to
start the client application. By default, these kinds of files are displayed in the product configuration
editor of Eclipse:
The application starts as soon as we click on the hyperlink “Launch an Eclipse application”. No
matter if we have already defined security, a log-on dialog will appear by default:
Page 168
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Log-on dialog
If security isn't in place, we will just have to select a proper host in combobox “Select host” in order
to connect to the application server. When pressing the "OK" button, the dialog disappears and the
application's main window is opened.
A Swing application can simply be launched by using file Application.java in the Package Explorer
and selecting “Run As → Java Application”.
For starting a RAP client we just select the project's root item in the Package Explorer of Eclipse
and select “Run As → RAP Application”.
If we haven't integrated the application server into Eclipse (e.g. by using Eclipse WTP), we will
have to deploy a JSF application to the target application server. After starting the application
server, we can open a browser and enter the application's start URL. Note that JBizMo uses the
entry in field project code (see chapter 6) as the application's context root. In the following
example, the project code is “dw” and thus we can insert http://localhost:8080/dw/ in the browser's
address field. Note that the default HTTP port (in this case 8080) depends on your personal
application server settings! If everything works fine, the browser will open the application's start
page:
Page 169
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
A Vaadin application must either be deployed on an application server or via its respective Spring
Boot main class (see chapter 6)!
If this has been finished successfully, we can open a browser and enter the application's root URL in
order to test our generated application.
Page 170
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
Page 171
http://sourceforge.net/projects/jbizmo/ Version 9.0.0 (May 2024)
19 Trademarks
• Oracle, GlassFish, MySQL, J2EE, Java EE and Java are registered trademarks of Oracle
and/or its affiliates. Other names may be trademarks of their respective owners.
• Jakarta EE, Eclipse and EclipseLink are trademarks of Eclipse Foundation, Inc.
• Microsoft, Microsoft SQL Server, Microsoft Excel, and Windows are either registered
trademarks or trademarks of Microsoft Corporation in the United States and/or other
countries.
Page 172