<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-523151633387570637</atom:id><lastBuildDate>Mon, 19 Oct 2026 07:42:21 +0000</lastBuildDate><category>Spring</category><category>HIbernate</category><category>JPA</category><category>ORM</category><category>Spring 4</category><category>Spring Boot</category><category>multitenancy</category><category>spring boot 2</category><category>spring security 5</category><category>Authentication</category><category>Salesforce Apex</category><category>cache</category><category>existing MVC</category><category>jdbc</category><category>login form extra field</category><category>multitenant</category><category>mysql</category><category>spring mvc</category><category>windows</category><category>.net</category><category>Attribute</category><category>AttributeConverter</category><category>CRUD operations</category><category>Cipher</category><category>Convert</category><category>Converter</category><category>DateTime</category><category>Entity</category><category>Force.com API</category><category>HTML forms</category><category>JSON</category><category>JVM arguments</category><category>Key</category><category>Meta data</category><category>POJO</category><category>REST</category><category>RestController OAuth2</category><category>SOQL</category><category>SOSL</category><category>SaaS</category><category>Salesforce</category><category>Salesforce API</category><category>Salesforce REST</category><category>Spring 5</category><category>Spring RestTemplate</category><category>Spring framework</category><category>Spring security</category><category>Time</category><category>Timezone</category><category>UTC</category><category>add tenant at runtime</category><category>add websockets</category><category>autocomplete</category><category>browser</category><category>browser cache</category><category>browsing history</category><category>cache buster</category><category>clear cache</category><category>connector/j</category><category>cookies</category><category>crypto</category><category>css</category><category>database per tenant</category><category>decrypt</category><category>domain model</category><category>dynamic tenants</category><category>encrypt</category><category>faster jackson</category><category>hibernate 5</category><category>hikari cp</category><category>html5</category><category>images</category><category>internet explorer</category><category>java</category><category>javascript</category><category>javascript object notation</category><category>jquery</category><category>keycloak</category><category>legacy apps</category><category>no server restart</category><category>progress</category><category>progress bar</category><category>proxy server</category><category>resource handling</category><category>resource versioning</category><category>retrofit MVC</category><category>security</category><category>setting timezone</category><category>sockjs</category><category>spring JPA</category><category>spring data</category><category>static resources</category><category>stomp</category><category>tenant per database</category><category>thread</category><category>threads</category><category>twitter bootstrap</category><category>update</category><category>vb.net</category><category>visual studio</category><category>vs2010</category><category>websocket</category><category>websockets in existing MVC</category><category>xml config</category><title>Sunit Katkar&#39;s blog</title><description>Just a blog about software development.</description><link>http://sunitkatkar.blogspot.com/</link><managingEditor>noreply@blogger.com (Sunit)</managingEditor><generator>Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-270917742192108521</guid><pubDate>Mon, 06 Jul 2020 01:23:00 +0000</pubDate><atom:updated>2020-10-18T12:33:36.002-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Authentication</category><category domain="http://www.blogger.com/atom/ns#">connector/j</category><category domain="http://www.blogger.com/atom/ns#">HIbernate</category><category domain="http://www.blogger.com/atom/ns#">jdbc</category><category domain="http://www.blogger.com/atom/ns#">JPA</category><category domain="http://www.blogger.com/atom/ns#">keycloak</category><category domain="http://www.blogger.com/atom/ns#">ORM</category><category domain="http://www.blogger.com/atom/ns#">security</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>Setting up Keycloak 10 with MySQL 8 on your Windows machine</title><description>Keycloak is a very good Identity and Access Management solution from Red Hat. It is open-source and works straight out of the box on most operating systems, including Windows. Keycloak allows you to secure your applications and services with the best in class security measures like OpenID, OAuth2, et-al. Please refer to the &lt;a href=&quot;https://www.keycloak.org/&quot; target=&quot;_blank&quot;&gt;official site&lt;/a&gt; for more details. &lt;br /&gt;&lt;br /&gt;I have started using it as the standard for all application security and user management needs. I will share my experiences of using Keycloak to secure Spring Boot traditional MVC apps as well as microservices in a future series of posts.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Purpose of this blog post&lt;/h2&gt;
There are many good resources on setting up Keycloak on your local machine and in the cloud. The &lt;a href=&quot;https://www.keycloak.org/docs/latest/getting_started/index.html&quot; target=&quot;_blank&quot;&gt;official documentation&lt;/a&gt; is a good place to start. &lt;br /&gt;&lt;br /&gt;
This blog post is NOT about setting up Keycloak to serve as a full fledged Identity and Access Management solution but about setting up an external database for Keycloak to store its data and the realms, users, roles, credentials, etc created by you. 
&lt;br /&gt;&lt;br /&gt;
Keycloak comes with a built-in in-memory H2 database out of the box. This is good for getting started with Keycloak on your development machine, but not recommended for using in a production environment.
&lt;b&gt;This blog post is about using a database like MySQL (version 8) as the Keycloak database instead of the default in-memory H2 database.&lt;/b&gt; Once you understand how it is done, then you can do the same on your production server.
&lt;br /&gt;&lt;br /&gt;
One small note - I am sharing my experiences and success on Windows and so this blog post will show how it is done on Windows. I am sure the same steps can be replicated after adjusting for other operating systems to achieve the same.&lt;br /&gt;&lt;br /&gt;

&lt;h2&gt;Problems when setting up on Windows 10&lt;/h2&gt;
I use Windows as my development machine and I came across &lt;u&gt;many errors and failed to set up KeyCloak with MySQL on my Windows machine&lt;/u&gt; at first go, despite following the &lt;a href=&quot;https://www.keycloak.org/docs/latest/server_installation/index.html#_database&quot; target=&quot;_blank&quot;&gt;official documentation&lt;/a&gt; and some blog posts. This is my attempt to record this here so that it might be useful to some of you who face problems setting up on Windows. &lt;br /&gt;&lt;br /&gt;
Here is a small subset of the issues I faced -&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://issues.redhat.com/browse/KEYCLOAK-3873?attachmentOrder=desc&quot; target=&quot;_blank&quot;&gt;Issue 1 - Failure to initialize database with MySQL ...&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://access.redhat.com/solutions/3077671&quot; target=&quot;_blank&quot;&gt;Issue 2 - Character set utf8mb4 is not supported for MySQL/MariaDB ...&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/3489041/mysqlerror-specified-key-was-too-long-max-key-length-is-1000-bytes&quot; target=&quot;_blank&quot;&gt;Issue 3 - Mysql::Error: Specified key was too long; max key length is 1000 bytes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://keycloak.discourse.group/t/challenge-with-setting-up-mysql/1397/5&quot; target=&quot;_blank&quot;&gt;Issue 4 - Challenge with setting up MySQL&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;
Basically Keycloak was able to connect with a local Postgresql database but not with a MySQL database. So after lot of searching and trying things on my own, borrowing from my experience, I was able to make it all work. I noted down the steps I performed. Now I am sharing them so that you can save time if you face similar issues.
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;
Versions used in this blog post&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Keycloak 10.0.2 - &lt;a href=&quot;https://www.keycloak.org/downloads&quot; target=&quot;_blank&quot;&gt;Download&lt;/a&gt;
    &lt;ul&gt;&lt;li&gt;Follow the &lt;a href=&quot;https://www.keycloak.org/docs/latest/getting_started/&quot; target=&quot;_blank&quot;&gt;official guide&lt;/a&gt; to setup the server. I have installed it to &lt;tt&gt;D:\keycloak&lt;/tt&gt; on my Windows machine. &lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;MySQL Community Server 8.0.20 - &lt;a href=&quot;https://dev.mysql.com/downloads/mysql/&quot; target=&quot;_blank&quot;&gt;Download&lt;/a&gt;
    &lt;ul&gt;&lt;li&gt;Follow the &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/windows-installation.html&quot; target=&quot;_blank&quot;&gt;official guide&lt;/a&gt; to setup the database server. I have used WampServer to install MySQL versions 5 and 8 on my Windows machine. Details in the next section.&lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;MySQL Connector for Java (Connector/J) - &lt;a href=&quot;https://dev.mysql.com/downloads/connector/j/&quot; target=&quot;_blank&quot;&gt;Download&lt;/a&gt; 
    &lt;ul&gt;&lt;li&gt;This is needed for Keycloak to talk to the MySQL database. I have downloaded the latest Platform Independent version &lt;tt&gt;mysql-connector-java-8.0.20.jar&lt;/tt&gt;        &lt;/li&gt;
       &lt;li&gt;Extract and place this jar file in a convenient location for adding it to the module as explained in later sections. I have placed it in &lt;tt&gt;D:\&lt;/tt&gt; on my Windows machine.&lt;/li&gt;
    &lt;/ul&gt; 
    &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h2&gt;Useful tools&lt;/h2&gt;
Though I prefer the command line for many tasks, sometimes a GUI tool helps getting things done quicker. I use the following tools. You don&#39;t have to use the same or use such tools at all.
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;HeidiSQL&lt;/b&gt; - Database Management GUI tool - &lt;a href=&quot;https://www.heidisql.com/&quot; target=&quot;_blank&quot;&gt;Download&lt;/a&gt;
  		&lt;ul&gt;&lt;li&gt;This is a free open-source tool, actively maintained and released with new features and bug fixes, which I find very useful.&lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;b&gt;WampServer&lt;/b&gt; - &lt;a href=&quot;http://wampserver.aviatechno.net/&quot; target=&quot;_blank&quot;&gt;Download from an aletrnative site which has more related options and tools&lt;/a&gt;
        &lt;ul&gt;&lt;li&gt;This is a free open-source tool which installs the MySQL, Apache HTTP server and PHP stack - LAMP stack on your Windows machine. It also allows you to  
          have multiple versions of MySQL on your machine as some of your projects might still be on legacy MySQL version 5.7.x &lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;br /&gt;
&lt;h2&gt;Assumptions&lt;/h2&gt;
I am assuming that you have installed Keycloak and MySQL. You have configured them enough to be operational as intended. Please go through the official documentation of each to setup and configure just enough. I will show you how the Connector/J comes into the picture further down.
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Basic Steps&lt;/h2&gt;
Keycloak uses the &lt;a href=&quot;https://wildfly.org/&quot; target=&quot;_blank&quot;&gt;JBoss Wildfly&lt;/a&gt; server under the hood. If you know how to use the JBoss/Wildfly CLI and add a datasource to Wildfly, then you might not need to follow all the steps shown here.&lt;br /&gt;&lt;br /&gt;
Here are the basic steps for configuring your MySQL database as the Keycloak database.
&lt;ul&gt;
  &lt;li&gt;Create a MySQL database, say, &lt;b&gt;&lt;tt&gt;keycloakdb&lt;/tt&gt;&lt;/b&gt; with a user, say, &lt;b&gt;&lt;tt&gt;keycloakadmin&lt;/tt&gt;&lt;/b&gt; in your MySQL and grant all privileges to this user&lt;/li&gt;
    &lt;li&gt;Add a module to the Keycloak (Wildfly) server defining your MySQL database and define a datasource along with the &lt;b&gt;database driver (Connector/J)&lt;/b&gt;, database user credentials, etc.&lt;/li&gt;
  &lt;li&gt;Restart your Keycloak server&lt;/li&gt;
&lt;/ul&gt;
I will detail every step next.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Using JBoss/Wildfly CLI&lt;/h2&gt;
The official documentation shows the files in Keycloak that you need to edit to configure your database. I have found that manually editing the files can sometimes lead to a problem. I could not pin point the exact reason when I tried, but being a newbie with Wildfly, I realized that using the CLI is a much better way to achieve these steps. Using the CLI works; and you don&#39;t have to troubleshoot if your configuration did not work as intended.
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Step 1: Create a database in MySQL&lt;/h2&gt;
Using the MySQL shell (or a GUI tool) create a database in MySQL with the &lt;tt&gt;utf8&lt;/tt&gt; character set and the collation as &lt;tt&gt;utf8_unicode_ci&lt;/tt&gt;. This is important as Keycloak requires UTF8 (for a few columns) and the official documentation states so &lt;a href=&quot;https://www.keycloak.org/docs/latest/server_installation/index.html#mysql-database&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;DATABASE&lt;/span&gt; keycloakdb &lt;span style=&quot;color: #007020;&quot;&gt;CHARACTER&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;SET&lt;/span&gt; utf8 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;COLLATE&lt;/span&gt; utf8_unicode_ci;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Step 2: Create a database user for Keycloak&lt;/h2&gt;
Now you need to create a user and grant privileges. Follow these commands if you are using the MySQL command line (and not a GUI tool). Note that I have used a simple password which is not secure. On production systems, the passwords need to be very secure with features like upper and lower case characters, special characters, numbers, etc. For purpose of this blog post, a simple password is good enough.
&lt;br /&gt;&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;USER&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;keycloakadmin&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;%&#39;&lt;/span&gt; IDENTIFIED &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;WITH&lt;/span&gt; mysql_native_password &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;BY&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;keycloak123&#39;&lt;/span&gt;;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;Why use &lt;tt&gt;mysql_native_password&lt;/tt&gt; when creating a user?&lt;/h3&gt;
From MySQL 8.0.x, &lt;b&gt;&lt;tt&gt;caching_sha2_password&lt;/tt&gt;&lt;/b&gt; is the default authentication plugin. Upto MySQL 5.x the default authentication plugin was &lt;b&gt;&lt;tt&gt;mysql_native_password&lt;/tt&gt;&lt;/b&gt;. Since a development environment, like mine, has two different versions of MySQL to support some legacy projects, I recommend using the older &lt;tt&gt;mysql_native_password&lt;/tt&gt; authentication plugin. If you are just using the latest MySQL 8 for all your development, then you need not use the &lt;tt&gt;mysql_native_password&lt;/tt&gt; keyword in the SQL command shown above.
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Step 3: Grant all privileges&lt;/h2&gt;
You can fine tune the privileges later by reading the Keycloak documentation in detail or talking to your DBA, but for setting up the Keycloak database user, just grant all privileges initially. As far as I know, I am sure that the database user requires all privileges.&lt;br /&gt;&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;GRANT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;ALL&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;PRIVILEGES&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;ON&lt;/span&gt; keycloakdb.&lt;span style=&quot;color: #333333;&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;TO&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;keycloakadmin&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;%&#39;&lt;/span&gt;;
&lt;span style=&quot;color: #888888;&quot;&gt;--- Tell the server to reload the grant tables&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;--- by performing a flush privileges operation&lt;/span&gt;
FLUSH &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;PRIVILEGES&lt;/span&gt;;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Step 4: Ensure that your databse engine is InnoDB&lt;/h2&gt;
MySQL has several database storage engines with &lt;b&gt;&lt;tt&gt;MyISAM&lt;/tt&gt;&lt;/b&gt; and &lt;b&gt;&lt;tt&gt;InnoDB&lt;/tt&gt;&lt;/b&gt; being the most prominent. There are many reasons to use one over the other, but that discussion is beyond the scope of this blog post. After reading a lot about this topic, like the documentation for Keycloak and MySQL 8, I found that &lt;b&gt;for the Keycloak database, MySQL 8 storage engine should be set to InnoDB&lt;/b&gt;, if it is not set already.&lt;br /&gt;&lt;br /&gt;
You can check the storage engine by following the MySQL &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/storage-engine-setting.html&quot; target=&quot;_blank&quot;&gt;documentation&lt;/a&gt; or by using MySQL commands like the following - &lt;br /&gt;&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;color: #888888;&quot;&gt;--- Should output: default_storage_engine InnoDB&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;SHOW&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;GLOBAL&lt;/span&gt; variables &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;like&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;&quot;default_storage%&quot;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;--- If storage engine is not InnoDB, use this to set it&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;SET&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;GLOBAL&lt;/span&gt; default_storage_engine &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;InnoDB&#39;&lt;/span&gt;;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;

&lt;h2&gt;Step 5: Adding a module with the MySQL driver (Connector/J) to Keycloak&lt;/h2&gt;
This is about telling Keycloak the database connector/driver you will be using to connect Keycloak to your MySQL database. As I said earlier, I have realized that using the JBoss/Wildfly CLI is the optimal way to configure Keycloak. So I will show you how to add a module using the CLI.&lt;br /&gt;&lt;br /&gt;
You need to run the Keycloak server so that the JBoss/Wildfly CLI tool can connect to the running server and further actions can be performed.&lt;br /&gt;&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;From the &lt;b&gt;/bin&lt;/b&gt; directory of your keycloak installation, run the &lt;b&gt;standalone.bat&lt;/b&gt; batch file.
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX0zxAtH17YodZOzn7k3Y26Vm-BVvdRz7mPZ_1KwsRFz5MhMWdsjR7pKg2mced8SY0bgiNLlbyUkyCj09KB1vrJsieNk0V1CXErm4Bb5UE97QHAX2wGOiCiNgmkWAJTX19BFX7o1a32eoS/s451/fig-02.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;100&quot; data-original-width=&quot;451&quot; height=&quot;142&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX0zxAtH17YodZOzn7k3Y26Vm-BVvdRz7mPZ_1KwsRFz5MhMWdsjR7pKg2mced8SY0bgiNLlbyUkyCj09KB1vrJsieNk0V1CXErm4Bb5UE97QHAX2wGOiCiNgmkWAJTX19BFX7o1a32eoS/w640-h142/fig-02.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;Your command/console window should now show you the regular Keycloak messages and indicate that the server is running. &lt;br /&gt;&lt;br /&gt;
Start another command prompt.
&lt;br /&gt;&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;From the &lt;b&gt;/bin&lt;/b&gt; directory of your keycloak installation, run the &lt;b&gt;jboss-cli.bat&lt;/b&gt; batch file.
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV4HWBxUsGGuviZerh-wNBnzeAvo9ugnpHpVKqe76wN4CvvEV9vf-zXjVxBTOGbqm-LObd6EX7LX-i7D8jYIav9dDK0xy6w2zVx8ZeWhmLXSG_hfMFCYnr_IsONJVL17BYe_OhP5HrTZIr/s720/fig-04.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;142&quot; data-original-width=&quot;720&quot; height=&quot;126&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV4HWBxUsGGuviZerh-wNBnzeAvo9ugnpHpVKqe76wN4CvvEV9vf-zXjVxBTOGbqm-LObd6EX7LX-i7D8jYIav9dDK0xy6w2zVx8ZeWhmLXSG_hfMFCYnr_IsONJVL17BYe_OhP5HrTZIr/w640-h126/fig-04.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;Now enter the &lt;b&gt;connect&lt;/b&gt; command to connect to the Keycloak server.
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigjrsFYRiTMvseGbjlNkBfifwrjpmJT09xHsbYTBrZdcrp2QJgo7kztURx83305Z-kI3FBfNS7RLHY9ChFsYLw8RVCoX9ZSVDidmxWib8aLPI2tRTkd6IFpSRI96LrAqVvbHYG0oRy_6Vx/s721/fig-05.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;157&quot; data-original-width=&quot;721&quot; height=&quot;140&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigjrsFYRiTMvseGbjlNkBfifwrjpmJT09xHsbYTBrZdcrp2QJgo7kztURx83305Z-kI3FBfNS7RLHY9ChFsYLw8RVCoX9ZSVDidmxWib8aLPI2tRTkd6IFpSRI96LrAqVvbHYG0oRy_6Vx/w640-h140/fig-05.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now enter the following command on the console. Note that the command is all in one line. If it is showing up in multiple lines, then it is because of the responsive
design and layout of this blog post.&lt;br /&gt;
&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;module add --name=com.mysql --dependencies=javax.api,javax.transaction.api --resources=D:/mysql-connector-java-8.0.20.jar --module-root-dir=../modules/system/layers/keycloak/
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvszQ0X1ypktZ48-RM_py_IP3lGovDJS9dvAiCcGOpyQYgTQ3YldNllAu5-4s_44cca5enlGLU1qb1KmO_piv73m-KQTnJ2WNuRWiU_JNdvdt_p38QCghGEiuNPO4Pf0COhakiu4cny4Aq/s1097/fig-06.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;197&quot; data-original-width=&quot;1097&quot; height=&quot;115&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvszQ0X1ypktZ48-RM_py_IP3lGovDJS9dvAiCcGOpyQYgTQ3YldNllAu5-4s_44cca5enlGLU1qb1KmO_piv73m-KQTnJ2WNuRWiU_JNdvdt_p38QCghGEiuNPO4Pf0COhakiu4cny4Aq/w640-h115/fig-06.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h3&gt;What did this &lt;tt&gt;module add&lt;/tt&gt; command do?&lt;/h3&gt;
The above command created a directory structure inside your &lt;tt&gt;{Keycloak-Directory}\modules\system\layers\keycloak/&lt;/tt&gt; directory and added a &lt;tt&gt;module.xml&lt;/tt&gt; file. After executing the &lt;tt&gt;module add&lt;/tt&gt; command you should see a module file at &lt;tt&gt;D:\keycloak\keycloak-10.0.2\modules\system\layers\keycloak\com\mysql\main\&lt;b&gt;module.xml&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;
The &lt;tt&gt;module.xml&lt;/tt&gt; file looks like the XML snippet below. Notice that the connector jar has also been copied inside this newly created directory by this command. So now Keycloak knows the definition of your database connector and the location of the jar file too.&lt;br /&gt;&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;color: #557799;&quot;&gt;&amp;lt;?xml version=&#39;1.0&#39; encoding=&#39;UTF-8&#39;?&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;module&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;xmlns=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;urn:jboss:module:1.1&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;com.mysql&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;resource-root&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;path=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;mysql-connector-java-8.0.20.jar&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;

    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;module&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;javax.api&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;module&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;javax.transaction.api&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/module&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Step 6: Defining a data source&lt;/h2&gt;
Now that Keycloak knows about the database connector through its modules, its time to actually define a data source. This will allow Keycloak to connect to your MySQL database instead of the built-in H2 database. &lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;First, go to your &lt;tt&gt;{Keycloak-Directory}\standalone\configuration\&lt;/tt&gt; and open the &lt;b&gt;&lt;tt&gt;standalone.xml&lt;/tt&gt;&lt;/b&gt; file in your text editor. &lt;/li&gt;
  &lt;li&gt;Search for the word &lt;b&gt;&lt;tt&gt;KeycloakDS&lt;/tt&gt;&lt;/b&gt; and you should see a section defining a data source and database driver for the default H2 database the XML snippet below.&lt;/li&gt;
  &lt;li&gt;You need to do two things - replace the &lt;b&gt;&lt;tt&gt;KeycloakDS&lt;/tt&gt;&lt;/b&gt; data source and the database connection driver defined for H2 with your MySQL database.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;datasource&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;jndi-name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;java:jboss/datasources/KeycloakDS&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;pool-name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;KeycloakDS&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;enabled=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;true&quot;&lt;/span&gt; 
    &lt;span style=&quot;color: #0000cc;&quot;&gt;use-java-context=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;true&quot;&lt;/span&gt; 
    &lt;span style=&quot;color: #0000cc;&quot;&gt;statistics-enabled=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;connection-url&amp;gt;&lt;/span&gt;jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/connection-url&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;driver&amp;gt;&lt;/span&gt;h2&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/driver&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;security&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;user-name&amp;gt;&lt;/span&gt;sa&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/user-name&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;password&amp;gt;&lt;/span&gt;sa&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/password&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/security&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/datasource&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;drivers&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;driver&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;h2&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;module=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;com.h2database.h2&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;xa-datasource-class&amp;gt;&lt;/span&gt;org.h2.jdbcx.JdbcDataSource&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/xa-datasource-class&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/driver&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/drivers&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
The above two tasks can be achieved using the CLI (and I recommend this versus manually editing the configuration in standalone.xml)
&lt;br /&gt;&lt;br /&gt;
&lt;h4&gt;Remove the existing datasource&lt;/h4&gt;
&lt;ul&gt;&lt;li&gt;Enter the following command in the console to first remove the &lt;b&gt;KeycloakDS&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;/subsystem=datasources/data-source=KeycloakDS:remove
&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;&lt;li&gt;You should see console messages indicating success, like in the screen shot below.&lt;/li&gt;&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq9yOQCumzMBfkCZ-juG8JHIbRQqosWvWIi8eMssBEa6YMSlc9r3O-9fe3Waw4PcOBW3r1z6dy7eh8fky8t-MSWfMG68VxaQkMlWksexpfun8m2J2vELPWWPoP1qE8Itij-LCfI_0hsUrU/s806/fig-07.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;225&quot; data-original-width=&quot;806&quot; height=&quot;178&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq9yOQCumzMBfkCZ-juG8JHIbRQqosWvWIi8eMssBEa6YMSlc9r3O-9fe3Waw4PcOBW3r1z6dy7eh8fky8t-MSWfMG68VxaQkMlWksexpfun8m2J2vELPWWPoP1qE8Itij-LCfI_0hsUrU/w640-h178/fig-07.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;Define your MySQL based driver and data source&lt;/h4&gt;
&lt;ul&gt;&lt;li&gt;Enter the following command in the console to define the MySQL &lt;b&gt;driver&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;/subsystem=datasources/jdbc-driver=mysql:add(driver-name=mysql,driver-module-name=com.mysql,driver-class-name=com.mysql.cj.jdbc.Driver)&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;You should see console messages indicating success, like in the screen shot below.&lt;/li&gt;&lt;/ul&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1ypMtzX2D7qpMDjaJvGGelsSIx6yiTK17GNgvJ7IKqhNtvME8r2tm21LFSNUQycaJJN6-qDXh1uuxRdjn6xom30XLUOAwxrNs6wv1O9iTP5ACaXRih5hip0GmsPrSSrpZORyLyWCfLglD/s1093/fig-011.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;168&quot; data-original-width=&quot;1093&quot; height=&quot;98&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1ypMtzX2D7qpMDjaJvGGelsSIx6yiTK17GNgvJ7IKqhNtvME8r2tm21LFSNUQycaJJN6-qDXh1uuxRdjn6xom30XLUOAwxrNs6wv1O9iTP5ACaXRih5hip0GmsPrSSrpZORyLyWCfLglD/w640-h98/fig-011.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;ul&gt;&lt;li&gt;Enter the following command in the console to define the MySQL &lt;b&gt;data source&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;data-source add --name=KeycloakDS --jndi-name=java:jboss/datasources/KeycloakDS --enabled=true --password=keycloak123 --user-name=keycloakadmin --driver-name=com.mysql --use-java-context=true --connection-url=jdbc:mysql://localhost:3306/keycloakdb?useSSL=false&amp;amp;characterEncoding=UTF-8
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;You should see console messages indicating success, like in the screen shot below.&lt;/li&gt;&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGccinWriVZ3wXGncBNB7iSQAs2pKKDZg2_LTZMZvHIqfuFkq9zInTGn_4Natz4XZEKRa6e-Rpyb1SH2KiCZn3pTEztodbAIEF3ZUVDCqSv5x4czJxrDgguKID5a-4Vpa2dCeyq3Me0pQS/s1070/fig-09.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;147&quot; data-original-width=&quot;1070&quot; height=&quot;88&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGccinWriVZ3wXGncBNB7iSQAs2pKKDZg2_LTZMZvHIqfuFkq9zInTGn_4Natz4XZEKRa6e-Rpyb1SH2KiCZn3pTEztodbAIEF3ZUVDCqSv5x4czJxrDgguKID5a-4Vpa2dCeyq3Me0pQS/w640-h88/fig-09.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;
&lt;ul&gt;&lt;li&gt;If you take a quick look at your &lt;b&gt;&lt;tt&gt;standalone.xml&lt;/tt&gt;&lt;/b&gt; file, your data source should now look like the XML snippet below&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;datasource&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;jndi-name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;java:jboss/datasources/KeycloakDS&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;pool-name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;KeycloakDS&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;enabled=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;use-java-context=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;connection-url&amp;gt;&lt;/span&gt;jdbc:mysql://localhost:3306/keycloakdb?useSSL=false&lt;span style=&quot;color: #880000; font-weight: bold;&quot;&gt;&amp;amp;amp;&lt;/span&gt;characterEncoding=UTF-8&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/connection-url&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;driver&amp;gt;&lt;/span&gt;com.mysql&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/driver&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;security&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;user-name&amp;gt;&lt;/span&gt;keycloakadmin&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/user-name&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;password&amp;gt;&lt;/span&gt;keycloak123&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/password&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/security&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/datasource&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;drivers&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;driver&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;h2&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;module=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;com.h2database.h2&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;xa-datasource-class&amp;gt;&lt;/span&gt;org.h2.jdbcx.JdbcDataSource&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/xa-datasource-class&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/driver&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;driver&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;com.mysql&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;module=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;com.mysql&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;driver-class&amp;gt;&lt;/span&gt;com.mysql.cj.jdbc.Driver&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/driver-class&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/driver&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/drivers&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;ul&gt;
  &lt;li&gt;There is much more you can do to the datasource configuration like add connection pooling, connection validators, exception handlers, etc. I have not covered all these options as the purpose is to get MySQL connected as the Keycloak database for a development environment. Detailed official documentation about Wildfly server and data sources is available &lt;a href=&quot;https://docs.wildfly.org/18/Admin_Guide.html#DataSource&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For example, you can manually add connection pooling to the data source configuration (or use the JBoss/Wildfly CLI options) like the XML snippet below.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;...
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;driver&amp;gt;&lt;/span&gt;com.mysql&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/driver&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;pool&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;min-pool-size&amp;gt;&lt;/span&gt;4&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/min-pool-size&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;initial-pool-size&amp;gt;&lt;/span&gt;4&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/initial-pool-size&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;max-pool-size&amp;gt;&lt;/span&gt;64&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/max-pool-size&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/pool&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;security&amp;gt;&lt;/span&gt;
...
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;You can add some validators to your data source like the XML snippet below. &lt;/li&gt;&lt;/ul&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;...
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/security&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;validation&amp;gt;&lt;/span&gt;
      &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;valid-connection-checker&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;class-name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;validate-on-match&amp;gt;&lt;/span&gt;true&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/validate-on-match&amp;gt;&lt;/span&gt;
      &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;exception-sorter&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;class-name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/validation&amp;gt;&lt;/span&gt; 
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/datasource&amp;gt;&lt;/span&gt;
...
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;About the character encoding parameter in the jdbc connection url&lt;/h4&gt;
Please note that Keycloak requires that your database be capable of storing data in UTF8 format. Similarly, the connection url also needs to specify that the connection can handle UTF8 data. More details in the official guide &lt;a href=&quot;https://www.keycloak.org/docs/latest/server_installation/#mysql-database&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.
&lt;br /&gt;&lt;br /&gt;
&lt;h4&gt;Test your database connection&lt;/h4&gt;
After the above two steps you should test if Keycloak can reach your database. 
&lt;ul&gt;&lt;li&gt;Enter the following command in the console to test database connectivity&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;/subsystem=datasources/data-source=KeycloakDS:test-connection-in-pool
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;You should see console messages indicating success, like in the screen shot below.&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-WOjLzHup68P8xFl7B2HB4PIZQCl5dM4CINLbHS3t2y9HaZvWP9hTH0_r7xSM-3cJMEEp5TFLAyGNkU2izbVHLzclG3bmzp30jpnnkVTKrQqIe7ra26pMZA3zWpkskTXaaPBsnzJTgUIJ/s1037/fig-010.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;177&quot; data-original-width=&quot;1037&quot; height=&quot;110&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-WOjLzHup68P8xFl7B2HB4PIZQCl5dM4CINLbHS3t2y9HaZvWP9hTH0_r7xSM-3cJMEEp5TFLAyGNkU2izbVHLzclG3bmzp30jpnnkVTKrQqIe7ra26pMZA3zWpkskTXaaPBsnzJTgUIJ/w640-h110/fig-010.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Step 7: Database configuration&lt;/h2&gt;
You are near the very end of your configuration, but please understand the following. Keycloak allows you to customize code and configuration via their SPI or Service Provider Interface facility. For the database configuration it means ensuring that some of the parameters are set properly for Keycloak to create the required tables and apply required constraints in the &lt;tt&gt;keycloakdb&lt;/tt&gt; database in your MySQL.&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
  &lt;li&gt;Open the &lt;tt&gt;standalone.xml&lt;/tt&gt; file once again in your text editor and search for &lt;b&gt;&lt;tt&gt;connectionsJpa&lt;/tt&gt;&lt;/b&gt;&lt;/li&gt;
  &lt;li&gt;You should see configuration like the XML snippet below&lt;/li&gt;
&lt;/ul&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;spi&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;connectionsJpa&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;provider&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;default&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;enabled=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
      &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;dataSource&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;value=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;java:jboss/datasources/KeycloakDS&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;initializeEmpty&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;value=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;migrationStrategy&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;value=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;update&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;migrationExport&quot;&lt;/span&gt; &lt;span style=&quot;color: #0000cc;&quot;&gt;value=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;${jboss.home.dir}/keycloak-database-update.sql&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/provider&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;/spi&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;This section is about telling Keycloak if you want your MySQL database to be initialized for you. Remember that Keycloak uses JPA too for connecting to your database. So the underlying provider is Hibernate. If you have ever worked with Hibernate then you know about configurations like &lt;tt&gt;ddl-auto&lt;/tt&gt;. These configuration parameters are something similar. Please refer to the official documentation &lt;a href=&quot;https://www.keycloak.org/docs/latest/server_installation/#database-configuration&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; for more details.&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Step 8: Restarting Keycloak server&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Note that Keycloak was started for configuring MySQL but its administrative UI was not accesssed nor was an administrator user added to it. It is not mandatory, but I prefer adding an intial admin user to Keycloak in the &lt;tt&gt;master&lt;/tt&gt; realm. You can add a admin user via the Keycloak Admin Console UI or via the Keycloak CLI. &lt;/li&gt;
  &lt;li&gt;Enter the following command from the &lt;b&gt;&lt;tt&gt;/bin&lt;/tt&gt;&lt;/b&gt; directory to add a Keycloak user to the master realm.&lt;/li&gt; &lt;/ul&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;add-user-keycloak.bat -u superadmin -p superadmin -r master
&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;&lt;li&gt;You are almost done! You need to restart Keycloak so that when it boots up, it will now use the &lt;tt&gt;KeycloakDS&lt;/tt&gt; data source and connect with your MySQL database. This will also allow you to check the tables and constraints added by Keycloak to your database.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h3&gt;Checking Keycloak log messages to see that MySQL connectivity is working as expected&lt;/h3&gt;
Once you restart the Keycloak server, you can check the log messages. You should see messages like the following, indicating success.&lt;br /&gt;
&lt;!--HTML generated using hilite.me--&gt;&lt;div style=&quot;background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;...
[org.jboss.as.connector.subsystems.datasources] (ServerService Thread Pool -- 32) WFLYJCA0005: Deploying non-JDBC-compliant driver class com.mysql.cj.jdbc.Driver (version 8.0)
...
org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-3) WFLYJCA0018: Started Driver service with driver-name = com.mysql
...
[org.hibernate.jpa.internal.util.LogHelper] (ServerService Thread Pool -- 59) HHH000204: Processing PersistenceUnitInfo [
        name: keycloak-default
        ...]
...
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h4&gt;About the log message - Deploying non-JDBC-compliant driver class com.mysql.cj.jdbc.Driver&lt;/h4&gt;
&lt;ul&gt;&lt;li&gt;Do not worry about that message. Your configuration will work despite this message. It is a known bug. Please see &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=62038&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;The simple explanation for this message is that the JDBC driver must have SQL support conforming to the entry level of the SQL92 standard. Unfortunately, MySQL does not support all features that are required by that standard. So JBoss/Wildfly just reports that the driver is not fully compliant. It does not affect the working of your MySQL as the Keycloak database.    
  &lt;/li&gt; &lt;/ul&gt;

&lt;h2&gt;Wrapping up&lt;/h2&gt;
You are now ready to use your MySQL database as the Keycloak data store. I have shown how to configure this on a Windows machine for development purpose. In a real life production scenario, you will probably not run a standalone instance of Keycloak; but most likely clustered mode. Please refer to the official documentation about &lt;a href=&quot;https://www.keycloak.org/docs/latest/server_installation/#_operating-mode&quot; target=&quot;_blank&quot;&gt;operating modes&lt;/a&gt;.These techniques I have shared will be applicable to those configurations too.&lt;br /&gt;&lt;br /&gt;
&lt;h4&gt;Happy Keycloak-ing! :)&lt;/h4&gt;
  

</description><link>http://sunitkatkar.blogspot.com/2020/07/setting-up-keycloak-10-with-mysql-8-on.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX0zxAtH17YodZOzn7k3Y26Vm-BVvdRz7mPZ_1KwsRFz5MhMWdsjR7pKg2mced8SY0bgiNLlbyUkyCj09KB1vrJsieNk0V1CXErm4Bb5UE97QHAX2wGOiCiNgmkWAJTX19BFX7o1a32eoS/s72-w640-h142-c/fig-02.png" height="72" width="72"/><thr:total>7</thr:total><georss:featurename>San Francisco, CA, USA</georss:featurename><georss:point>37.7749295 -122.4194155</georss:point><georss:box>10.170460778224783 -157.57566549999999 65.379398221775219 -87.263165500000014</georss:box></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-7288801960437270731</guid><pubDate>Tue, 11 Sep 2018 20:10:00 +0000</pubDate><atom:updated>2018-09-11T13:15:25.487-07:00</atom:updated><title>Spring Boot 2 + Thymeleaf - Versioning static assets for client side cache busting</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In a &lt;a href=&quot;https://sunitkatkar.blogspot.com/2016/04/preventing-caching-of-static-resources.html&quot; target=&quot;_blank&quot;&gt;post&lt;/a&gt; written some time ago, I showed how you can prevent caching of static resources (javascript and css) in a legacy Spring MVC application. Recently I needed to use the same technique to prevent browser side caching of javascript and css files in a Spring Boot 2 project using Thymeleaf as the view layer.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Purpose of this blog post&lt;/h2&gt;
&lt;br /&gt;
This blog post is about sharing a simple way to make your Spring Boot application serve versioned static resources like javascript and css files so that client side caching can be overcome when your static resources change. &lt;br /&gt;
Typically browsers download javascript and css files and then refer to them from the local cache. This is okay as long as you do not change the contents of your files. If you do make changes but you keep the same name then the browser will not know about the changes and use the same version from its local cache. Some approaches to defeat the cache are to add add a distinguishing query parameter (like myfile.css?v=1.1) or placing  the files in a new subdirectory (like /js/v2/myfile.js) and then updating all the places in the HTML files where these are included. This is tedious and error prone to manually update the version query parameter or rename the file location in all the pages that it is included.&lt;br /&gt;
&lt;br /&gt;
Fortunately Spring allows us to take care of this with minimal effort. Let us see how.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
What is used to build the example in this blog post?&lt;/h2&gt;
This example applies to a Spring Boot 2 application with Thymeleaf as the view layer. I am assuming that you have a standard Spring Boot 2 app with Thymeleaf. I am sure that this can be adapted to any other view technologies barring one as mentioned in the note below. &lt;br /&gt;
&lt;br /&gt;
Before you start, I recommend you refer to the &lt;a href=&quot;https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web.html#mvc-config-static-resources&quot; target=&quot;_blank&quot;&gt;official documentation&lt;/a&gt; about serving static resources for further clarity.&lt;br /&gt;
&lt;br /&gt;
Please note that if you are using Spring WebFlux then you cannot use this approach. See the &lt;a href=&quot;https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web-reactive.html#webflux-config-static-resources&quot; target=&quot;_blank&quot;&gt;official documentation&lt;/a&gt; here for more details.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Step 1: Adding entries to your application.properties (or application.yml) file&lt;/h2&gt;
You need to add the following three entries in your application.properties file. What these mean is explained very clearly on the Spring documentation &lt;a href=&quot;https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; in the Spring Resources Handling section.
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
File: application.properties&lt;/h3&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#########################################################&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#Adding ResourceUrlEncodingFilter i.e. to version static &lt;/span&gt;
&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#js and css files to prevent caching by browser&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#########################################################&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#Whether to enable the Spring Resource Handling chain. &lt;/span&gt;
&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#By default, disabled unless at least one strategy has &lt;/span&gt;
&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#been enabled.&lt;/span&gt;
spring.resources.chain.enabled=true

&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;# Whether to enable the content Version Strategy.&lt;/span&gt;
spring.resources.chain.strategy.content.enabled=true

&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#Comma-separated list of patterns to apply to the content &lt;/span&gt;
&lt;span style=&quot;color: #008800; font-style: italic;&quot;&gt;#Version Strategy i.e. where are your js and css files&lt;/span&gt;
spring.resources.chain.strategy.content.paths=/js/**,/css/**
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Step 2: Define a ResourceUrlEncodingFilter bean&lt;/h2&gt;
You need to create a &lt;a href=&quot;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.html&quot; target=&quot;_blank&quot;&gt;ResourceUrlEncodingFilter&lt;/a&gt; bean and register it in your application&#39;s filter chain. With Spring Boot, it is very simple. Just create a MVC configuration and instantiate the bean there. For example, the following is all you need.
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
File: CacheBusterMVCConfig.java&lt;/h3&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Component&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;CacheBusterMVCConfig&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;implements&lt;/span&gt; WebMvcConfigurer &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Define the ResourceUrlEncodingFilter as a bean. &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Add the &amp;lt;code&amp;gt;@ConditionalOnEnabledResourceChain&amp;lt;/code&amp;gt; &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * to ensure that the resource chain property &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &amp;lt;code&amp;gt;spring.resources.chain.enabled=true&amp;lt;/code&amp;gt; &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * is set to true in the &amp;lt;code&amp;gt;application.properties&amp;lt;/code&amp;gt; file.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Bean&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@ConditionalOnEnabledResourceChain&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; ResourceUrlEncodingFilter &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;resourceUrlEncodingFilter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;ResourceUrlEncodingFilter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Results&lt;/h2&gt;
If you download and run the project, you should see the screen as shown below.
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilthfeCrznKgswlFYhjDEFCgm_BtP-SSVU30dYo7j5yyz4J9pqVIKZgBbDcIVPCxP09FcH7SjoNMItiph3kLej5JceZI-OXyRf9dLJg1Rqoms57STsqG7ULzn_2R-NSypmuWGU8EWwoNr4/s1600/cache-buster-browser.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;700&quot; data-original-width=&quot;1246&quot; height=&quot;179&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilthfeCrznKgswlFYhjDEFCgm_BtP-SSVU30dYo7j5yyz4J9pqVIKZgBbDcIVPCxP09FcH7SjoNMItiph3kLej5JceZI-OXyRf9dLJg1Rqoms57STsqG7ULzn_2R-NSypmuWGU8EWwoNr4/s320/cache-buster-browser.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Resources&lt;/h2&gt;
The example project has been uploaded to Github &lt;a href=&quot;https://github.com/sunitk/springboot2-cachebuster&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. If you like it, please star my repo.
&lt;br /&gt;
&lt;br /&gt;
Happy coding :)
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2018/09/spring-boot-2-thymeleaf-versioning.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilthfeCrznKgswlFYhjDEFCgm_BtP-SSVU30dYo7j5yyz4J9pqVIKZgBbDcIVPCxP09FcH7SjoNMItiph3kLej5JceZI-OXyRf9dLJg1Rqoms57STsqG7ULzn_2R-NSypmuWGU8EWwoNr4/s72-c/cache-buster-browser.png" height="72" width="72"/><thr:total>9</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-7682959242673847389</guid><pubDate>Fri, 25 May 2018 22:56:00 +0000</pubDate><atom:updated>2018-09-04T10:11:09.903-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">add tenant at runtime</category><category domain="http://www.blogger.com/atom/ns#">database per tenant</category><category domain="http://www.blogger.com/atom/ns#">dynamic tenants</category><category domain="http://www.blogger.com/atom/ns#">hibernate 5</category><category domain="http://www.blogger.com/atom/ns#">JPA</category><category domain="http://www.blogger.com/atom/ns#">multitenancy</category><category domain="http://www.blogger.com/atom/ns#">no server restart</category><category domain="http://www.blogger.com/atom/ns#">spring boot 2</category><category domain="http://www.blogger.com/atom/ns#">spring security 5</category><title>Adding tenants without application restart in SaaS style multi-tenant web app with Spring Boot 2 and Spring Security 5</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In my previous posts (&lt;a href=&quot;https://sunitkatkar.blogspot.com/2018/04/building-saas-style-multi-tenant-web.html&quot; target=&quot;_blank&quot;&gt;part 1&lt;/a&gt;, &lt;a href=&quot;https://sunitkatkar.blogspot.com/2018/04/building-saas-style-multi-tenant-web2.html&quot; target=&quot;_blank&quot;&gt;part 2&lt;/a&gt;) about Saas style multi-tenant web applications, the focus was on how multi-tenancy is achieved.&amp;nbsp; In this post I will share how tenants can be added without restarting the application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Update 4th Sep 2018&lt;/h2&gt;
Many readers of this blog post have emailed me saying that they run the code but cannot login. This is because they have not populated the user table with username and password for a user nor have they created the necessary databases and schema. In many cases, the readers are not familiar with Spring Security.
I request that you please read up on Spring Security first. Here is an &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/current/guides/html5/form-javaconfig.html&quot; target=&quot;_blank&quot;&gt;excellent example&lt;/a&gt; from the official Spring documentation site.
&lt;br/&gt;&lt;br/&gt;
&lt;h2&gt;
Purpose of this blog post&lt;/h2&gt;
In my previous posts, I showed how to read the details of the tenant databases from the application.yml file. The focus was on how to set up SaaS style database per tenant multitenancy. &lt;br /&gt;
&lt;br /&gt;
In this post, I will show you how you can add the tenant information in a separate &#39;master&#39; database and the multi-tenant application will pick up the existing tenants and any tenant added while your application is running. If you were to add a new tenant in the application.yml file, then you would have to restart the application. With the technique I am about to describe, you do not need to restart your application.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Structure of the application&lt;/h2&gt;
In the previous posts, the application learnt about the tenants from the application.yml file. In this post, the tenant information is not learnt from the application.yml file but from a separate table in the master database.
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0Ketc4dm9h0Hgq4HB2mPjdFTJJ3X1gxYhow42k3PVmPMEqhTfS55fJStEgUhtwAiEfLGMuA3tHG8xqIExIfkn4JdGCudJnb4hSY4qTpYbrgll5JdM1Sx3l4OuVrge7m4Ei2ZF9Wt9xj5k/s1600/MTD-FIG-01.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;343&quot; data-original-width=&quot;534&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0Ketc4dm9h0Hgq4HB2mPjdFTJJ3X1gxYhow42k3PVmPMEqhTfS55fJStEgUhtwAiEfLGMuA3tHG8xqIExIfkn4JdGCudJnb4hSY4qTpYbrgll5JdM1Sx3l4OuVrge7m4Ei2ZF9Wt9xj5k/s1600/MTD-FIG-01.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The application.yml file is still required for application related properties and values, but the tenant database information need not be stored in it.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Datasources - One for the master database and one each for every tenant&lt;/h2&gt;
The tenant information will be stord in the master database. For example, if the master database is called &#39;masterdb&#39; and the table for tenant information is called &#39;master_tenant&#39;, then the information might look like this:
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsoJVCtjRdsFDQPxWMdVSmaPs_zx3nDkOZBxOYbxc5FwDlx6ZHdQoHVxtj7wuF-YnqqUDTT6eSWXGC0eNJcmxrRO1HQOPGKcSeiz9ZnyZ74kBkH6Iq7tXJ4yoD6BMAA-HUSBnJn1hjuEnN/s1600/MTD-FIG-02.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;187&quot; data-original-width=&quot;849&quot; height=&quot;140&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsoJVCtjRdsFDQPxWMdVSmaPs_zx3nDkOZBxOYbxc5FwDlx6ZHdQoHVxtj7wuF-YnqqUDTT6eSWXGC0eNJcmxrRO1HQOPGKcSeiz9ZnyZ74kBkH6Iq7tXJ4yoD6BMAA-HUSBnJn1hjuEnN/s640/MTD-FIG-02.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is a simple table with the datasource related information about each tenant, like url, username, password, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Order of setting up datasources and entity managers&lt;/h2&gt;
It is important how the data sources are set up. Earlier, the tenant information was from the application.yml file. So the only datasources being setup were for each tenant. 
&lt;br /&gt;
&lt;br /&gt;
The datasource for the &#39;master_tenant&#39; table needs to be setup first as this table contains the tenant information. Once this datasource is set up, it can be used to read the tenant information and set up a datasource per tenant.
&lt;br /&gt;
&lt;br /&gt;
Please pay attention to the package structures. The master and tenant related datasource configurations are kept in separate packages and the master datasource is set up first.
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx-wbe45lI5u4v5SvFzTGjk-oRWCRya-J_Ydql3mXTOwrwmceWGHcoKiNU8BhiwV0f6YGtdLqi0mHE48aVFON3rqmYNzNwZSsH_EhrM8-x7CmqV4FxiQxGwxqaQb_MLhV0QQ5CGuGZr3uf/s1600/MTD-FIG-03.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;603&quot; data-original-width=&quot;575&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx-wbe45lI5u4v5SvFzTGjk-oRWCRya-J_Ydql3mXTOwrwmceWGHcoKiNU8BhiwV0f6YGtdLqi0mHE48aVFON3rqmYNzNwZSsH_EhrM8-x7CmqV4FxiQxGwxqaQb_MLhV0QQ5CGuGZr3uf/s1600/MTD-FIG-03.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following source code listings show the way this is done. 
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;File: MasterDatabaseConfig.java&lt;/h3&gt;
This sets up the master datasource to connect to the masterdb database.
&lt;br/&gt;&lt;br/&gt;
&lt;!-- Start: Highlighted code --&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;div style=&quot;background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;&quot;&gt;&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;sunitkatkar&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;blogspot&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;master&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;java.util.Properties&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;javax.persistence.EntityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;javax.sql.DataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.slf4j.Logger&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.beans.factory.annotation.Qualifier&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.context.annotation.Primary&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.dao.annotation.&lt;/span&gt;
        PersistenceExceptionTranslationPostProcessor&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.data.jpa.repository.config.&lt;/span&gt;
        EnableJpaRepositories&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.orm.jpa.JpaTransactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.orm.jpa.JpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.orm.jpa.&lt;/span&gt;
        LocalContainerEntityManagerFactoryBean&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.orm.jpa.vendor.&lt;/span&gt;
        HibernateJpaVendorAdapter&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.transaction.annotation.&lt;/span&gt;
        EnableTransactionManagement&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.sunitkatkar.blogspot.master.model.MasterTenant&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.sunitkatkar.blogspot.master.repository.&lt;/span&gt;
        MasterTenantRepository&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.zaxxer.hikari.HikariDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * Configuration of the master database which holds information about tenants in&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * the application.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; *         (https://sunitkatkar.blogspot.com/)&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @since ver 1.0 (May 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Configuration&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@EnableTransactionManagement&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@EnableJpaRepositories&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;basePackages &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;com.sunitkatkar.blogspot.master.model&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
                                 &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;com.sunitkatkar.blogspot.master.repository&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;},&lt;/span&gt; 
                       entityManagerFactoryRef &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;masterEntityManagerFactory&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; 
                       transactionManagerRef &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;masterTransactionManager&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #BB0066; font-weight: bold&quot;&gt;MasterDatabaseConfig&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;final&lt;/span&gt; Logger LOG &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; LoggerFactory
            &lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getLogger&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;MasterDatabaseConfig&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Master database configuration properties like username, password, etc.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;private&lt;/span&gt; MasterDatabaseConfigProperties masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Creates the master datasource bean which is required for creating the&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * entity manager factory bean &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Note that using names for beans is not mandatory but it is a good&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * practice to ensure that the intended beans are being used where required.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;masterDataSource&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; DataSource &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;masterDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;

        LOG&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;Setting up masterDataSource with: &amp;quot;&lt;/span&gt;
                &lt;span style=&quot;color: #333333&quot;&gt;+&lt;/span&gt; masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;toString&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;

        HikariDataSource ds &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; HikariDataSource&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;

        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setUsername&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getUsername&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setPassword&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getPassword&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setJdbcUrl&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getUrl&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setDriverClassName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getDriverClassName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setPoolName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getPoolName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;

        &lt;span style=&quot;color: #888888&quot;&gt;// HikariCP settings&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// Maximum number of actual connection in the pool&lt;/span&gt;
        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setMaximumPoolSize&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getMaxPoolSize&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;

        &lt;span style=&quot;color: #888888&quot;&gt;// Minimum number of idle connections in the pool&lt;/span&gt;
        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setMinimumIdle&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getMinIdle&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;

        &lt;span style=&quot;color: #888888&quot;&gt;// Maximum waiting time for a connection from the pool&lt;/span&gt;
        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setConnectionTimeout&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getConnectionTimeout&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;

        &lt;span style=&quot;color: #888888&quot;&gt;// Maximum time that a connection is allowed to sit idle in the pool&lt;/span&gt;
        ds&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setIdleTimeout&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDbProperties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getIdleTimeout&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
        LOG&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;Setup of masterDataSource succeeded.&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; ds&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Creates the entity manager factory bean which is required to access the&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * JPA functionalities provided by the JPA persistence provider, i.e.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Hibernate in this case. &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Note the &amp;lt;b&amp;gt;{@literal @}Primary&amp;lt;/b&amp;gt; annotation which tells Spring boot to&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * create this entity manager as the first thing when starting the&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * application.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Primary&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;masterEntityManagerFactory&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; LocalContainerEntityManagerFactoryBean &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;masterEntityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(){&lt;/span&gt;
        LocalContainerEntityManagerFactoryBean em &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; 
                &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;LocalContainerEntityManagerFactoryBean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;

        &lt;span style=&quot;color: #888888&quot;&gt;// Set the master data source&lt;/span&gt;
        em&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterDataSource&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;

        &lt;span style=&quot;color: #888888&quot;&gt;// The master tenant entity and repository need to be scanned&lt;/span&gt;
        em&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setPackagesToScan&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; String&lt;span style=&quot;color: #333333&quot;&gt;[]{&lt;/span&gt;MasterTenant&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getPackage&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(),&lt;/span&gt;
                        MasterTenantRepository&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getPackage&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()});&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// Setting a name for the persistence unit as Spring sets it as&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// &amp;#39;default&amp;#39; if not defined&lt;/span&gt;
        em&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setPersistenceUnitName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;masterdb-persistence-unit&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #888888&quot;&gt;// Setting Hibernate as the JPA provider&lt;/span&gt;
        JpaVendorAdapter vendorAdapter &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; HibernateJpaVendorAdapter&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
        em&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setJpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;vendorAdapter&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #888888&quot;&gt;// Set the hibernate properties&lt;/span&gt;
        em&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setJpaProperties&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;hibernateProperties&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
        LOG&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;Setup of masterEntityManagerFactory succeeded.&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; em&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * This transaction manager is appropriate for applications that use a&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * single JPA EntityManagerFactory for transactional data access. &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Note the &amp;lt;b&amp;gt;{@literal @}Qualifier&amp;lt;/b&amp;gt; annotation to ensure that the&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &amp;lt;tt&amp;gt;masterEntityManagerFactory&amp;lt;/tt&amp;gt; is used for setting up the&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * transaction manager.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @param emf&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;masterTransactionManager&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; JpaTransactionManager &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;masterTransactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;
            &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Qualifier&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;masterEntityManagerFactory&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; EntityManagerFactory emf&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        JpaTransactionManager transactionManager &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; JpaTransactionManager&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
        transactionManager&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setEntityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;emf&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; transactionManager&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Bean post-processor that automatically applies persistence exception&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * translation to any bean marked with Spring&amp;#39;s @Repository annotation,&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * adding a corresponding PersistenceExceptionTranslationAdvisor to the&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * exposed proxy (either an existing AOP proxy or a newly generated proxy&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * that implements all of the target&amp;#39;s interfaces).&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; PersistenceExceptionTranslationPostProcessor &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;exceptionTranslation&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;PersistenceExceptionTranslationPostProcessor&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * The properties for configuring the JPA provider Hibernate.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;private&lt;/span&gt; Properties &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;hibernateProperties&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        Properties properties &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; Properties&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;DIALECT&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
                &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;org.hibernate.dialect.MySQL5Dialect&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;SHOW_SQL&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;FORMAT_SQL&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;HBM2DDL_AUTO&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;update&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; properties&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!-- End: Highlighted code --&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;h3&gt;File: TenantDatabaseConfig.java&lt;/h3&gt;
This class sets up the datasources for the tenant databases. Note that this class requires the &#39;MultiTenantConnectionProvider&#39; for the tenant datasources. These datasources are configured in the &#39;DataSourceBasedMultiTenantConnectionProviderImpl&#39; class, shown later on in this post.&lt;br/&gt;&lt;br/&gt;
&lt;!-- Start: Highlighted code --&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;div style=&quot;background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;&quot;&gt;&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;sunitkatkar&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;blogspot&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;tenant&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;java.util.HashMap&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;java.util.Map&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;javax.persistence.EntityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.hibernate.MultiTenancyStrategy&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.hibernate.context.spi.CurrentTenantIdentifierResolver&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.slf4j.Logger&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.beans.factory.annotation.Qualifier&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.boot.autoconfigure.condition.ConditionalOnBean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.context.annotation.ComponentScan&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.data.jpa.repository.config.EnableJpaRepositories&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.orm.jpa.JpaTransactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.orm.jpa.JpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.transaction.annotation.EnableTransactionManagement&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.sunitkatkar.blogspot.tenant.model.User&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.sunitkatkar.blogspot.tenant.repository.UserRepository&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.sunitkatkar.blogspot.tenant.service.UserService&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * This is the tenant data sources configuration which sets up the multitenancy.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; *         (https://sunitkatkar.blogspot.com/)&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @since ver 1.0 (May 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Configuration&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@EnableTransactionManagement&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@ComponentScan&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;basePackages &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;com.sunitkatkar.blogspot.tenant.repository&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;com.sunitkatkar.blogspot.tenant.model&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;})&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@EnableJpaRepositories&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;basePackages &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;com.sunitkatkar.blogspot.tenant.repository&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
        &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;com.sunitkatkar.blogspot.tenant.service&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;},&lt;/span&gt; 
        entityManagerFactoryRef &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantEntityManagerFactory&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; 
        transactionManagerRef &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantTransactionManager&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #BB0066; font-weight: bold&quot;&gt;TenantDatabaseConfig&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;final&lt;/span&gt; Logger LOG &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; LoggerFactory
            &lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getLogger&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;TenantDatabaseConfig&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;


    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantJpaVendorAdapter&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; JpaVendorAdapter &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;jpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;HibernateJpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantTransactionManager&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; JpaTransactionManager &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;transactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;
            EntityManagerFactory tenantEntityManager&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        JpaTransactionManager transactionManager &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; JpaTransactionManager&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
        transactionManager&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setEntityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;tenantEntityManager&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; transactionManager&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * The multi tenant connection provider&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;datasourceBasedMultitenantConnectionProvider&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@ConditionalOnBean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;masterEntityManagerFactory&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; MultiTenantConnectionProvider &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;multiTenantConnectionProvider&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// Autowires the multi connection provider&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;DataSourceBasedMultiTenantConnectionProviderImpl&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * The current tenant identifier resolver&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;currentTenantIdentifierResolver&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; CurrentTenantIdentifierResolver &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;currentTenantIdentifierResolver&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;CurrentTenantIdentifierResolverImpl&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Creates the entity manager factory bean which is required to access the&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * JPA functionalities provided by the JPA persistence provider, i.e.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Hibernate in this case.&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @param connectionProvider&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @param tenantResolver&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantEntityManagerFactory&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@ConditionalOnBean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;datasourceBasedMultitenantConnectionProvider&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; LocalContainerEntityManagerFactoryBean &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;entityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;
            &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Qualifier&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;datasourceBasedMultitenantConnectionProvider&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; 
            MultiTenantConnectionProvider connectionProvider&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Qualifier&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;currentTenantIdentifierResolver&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; 
            CurrentTenantIdentifierResolver tenantResolver&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;

        LocalContainerEntityManagerFactoryBean emfBean &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; LocalContainerEntityManagerFactoryBean&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;//All tenant related entities, repositories and service classes must be scanned&lt;/span&gt;
        emfBean&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setPackagesToScan&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; String&lt;span style=&quot;color: #333333&quot;&gt;[]&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt; User&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getPackage&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(),&lt;/span&gt;
                        UserRepository&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getPackage&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(),&lt;/span&gt;
                        UserService&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getPackage&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;});&lt;/span&gt;
        emfBean&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setJpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;jpaVendorAdapter&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
        emfBean&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setPersistenceUnitName&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantdb-persistence-unit&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        Map&lt;span style=&quot;color: #333333&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; Object&lt;span style=&quot;color: #333333&quot;&gt;&amp;gt;&lt;/span&gt; properties &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; HashMap&lt;span style=&quot;color: #333333&quot;&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;MULTI_TENANT&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
                MultiTenancyStrategy&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;SCHEMA&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;
                org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;MULTI_TENANT_CONNECTION_PROVIDER&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
                connectionProvider&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;
                org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;MULTI_TENANT_IDENTIFIER_RESOLVER&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
                tenantResolver&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// ImprovedNamingStrategy is deprecated and unsupported in Hibernate 5&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// properties.put(&amp;quot;hibernate.ejb.naming_strategy&amp;quot;,&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// &amp;quot;org.hibernate.cfg.ImprovedNamingStrategy&amp;quot;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;DIALECT&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt;
                &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;org.hibernate.dialect.MySQL5Dialect&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;SHOW_SQL&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;FORMAT_SQL&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        properties&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;org&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;hibernate&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;Environment&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;HBM2DDL_AUTO&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;update&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;

        emfBean&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setJpaPropertyMap&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;properties&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        LOG&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantEntityManagerFactory set up successfully!&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; emfBean&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!-- End: Highlighted code --&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;h3&gt;File: DataSourceBasedMultiTenantConnectionProviderImpl.java&lt;/h3&gt;
This sets up the multi-tenant connection properties required by Hibernate. This is different than the code you have seen in the past 2 blog posts. Here, the datasources are read from the &#39;master_tenant&#39; table and then stored in a map. This map is used to look up the datasource based on the tenant id. If a tenant is added to the &#39;master_tenant&#39; table while the application is running, then a request for that tenant will prompt this class to read the &#39;master_tenant&#39; table once again and recreate the datasource look up map. This is how the application becomes &#39;dynamic&#39; about using a tenant added at runtime.
&lt;br/&gt;&lt;br/&gt;
&lt;!-- Start: Highlighted code --&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;div style=&quot;background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;&quot;&gt;&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;sunitkatkar&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;blogspot&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;tenant&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;java.util.List&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;java.util.Map&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;java.util.TreeMap&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;javax.sql.DataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.hibernate.engine.jdbc.connections.&lt;/span&gt;
    spi&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;AbstractDataSourceBasedMultiTenantConnectionProviderImpl&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.slf4j.Logger&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.sunitkatkar.blogspot.master.model.MasterTenant&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.sunitkatkar.blogspot.master.repository.MasterTenantRepository&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold&quot;&gt;com.sunitkatkar.blogspot.util.DataSourceUtil&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * This class does the job of selecting the correct database based on the tenant&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * id found by the {@link CurrentTenantIdentifierResolverImpl}&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; *         (https://sunitkatkar.blogspot.com/)&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @since ver 1.0 (May 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; *&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Configuration&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #BB0066; font-weight: bold&quot;&gt;DataSourceBasedMultiTenantConnectionProviderImpl&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;extends&lt;/span&gt; AbstractDataSourceBasedMultiTenantConnectionProviderImpl &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;final&lt;/span&gt; Logger LOG &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; LoggerFactory
            &lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getLogger&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;DataSourceBasedMultiTenantConnectionProviderImpl&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;final&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold&quot;&gt;long&lt;/span&gt; serialVersionUID &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000DD; font-weight: bold&quot;&gt;1L&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Injected MasterTenantRepository to access the tenant information from the&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * master_tenant table&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;private&lt;/span&gt; MasterTenantRepository masterTenantRepo&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     * Map to store the tenant ids as key and the data source as the value&lt;/span&gt;
&lt;span style=&quot;color: #888888&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;private&lt;/span&gt; Map&lt;span style=&quot;color: #333333&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333&quot;&gt;,&lt;/span&gt; DataSource&lt;span style=&quot;color: #333333&quot;&gt;&amp;gt;&lt;/span&gt; dataSourcesMtApp &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; TreeMap&lt;span style=&quot;color: #333333&quot;&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;protected&lt;/span&gt; DataSource &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;selectAnyDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// This method is called more than once. So check if the data source map&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// is empty. If it is then rescan master_tenant table for all tenant&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// entries.&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;dataSourcesMtApp&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;())&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
            List&lt;span style=&quot;color: #333333&quot;&gt;&amp;lt;&lt;/span&gt;MasterTenant&lt;span style=&quot;color: #333333&quot;&gt;&amp;gt;&lt;/span&gt; masterTenants &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; masterTenantRepo&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;findAll&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
            LOG&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;&amp;gt;&amp;gt;&amp;gt;&amp;gt; selectAnyDataSource() -- Total tenants:&amp;quot;&lt;/span&gt;
                    &lt;span style=&quot;color: #333333&quot;&gt;+&lt;/span&gt; masterTenants&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;MasterTenant masterTenant &lt;span style=&quot;color: #333333&quot;&gt;:&lt;/span&gt; masterTenants&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
                dataSourcesMtApp&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterTenant&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getTenantId&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(),&lt;/span&gt; DataSourceUtil
                        &lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;createAndConfigureDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterTenant&lt;span style=&quot;color: #333333&quot;&gt;));&lt;/span&gt;
            &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;dataSourcesMtApp&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;iterator&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;


    &lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;protected&lt;/span&gt; DataSource &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;selectDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;String tenantIdentifier&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// If the requested tenant id is not present check for it in the master&lt;/span&gt;
        &lt;span style=&quot;color: #888888&quot;&gt;// database &amp;#39;master_tenant&amp;#39; table&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;(!&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;dataSourcesMtApp&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;containsKey&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;tenantIdentifier&lt;span style=&quot;color: #333333&quot;&gt;))&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
            List&lt;span style=&quot;color: #333333&quot;&gt;&amp;lt;&lt;/span&gt;MasterTenant&lt;span style=&quot;color: #333333&quot;&gt;&amp;gt;&lt;/span&gt; masterTenants &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; masterTenantRepo&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;findAll&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
            LOG&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;&amp;gt;&amp;gt;&amp;gt;&amp;gt; selectDataSource() -- tenant:&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;+&lt;/span&gt; tenantIdentifier
                    &lt;span style=&quot;color: #333333&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot; Total tenants:&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;+&lt;/span&gt; masterTenants&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;());&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;MasterTenant masterTenant &lt;span style=&quot;color: #333333&quot;&gt;:&lt;/span&gt; masterTenants&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
                dataSourcesMtApp&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterTenant&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;getTenantId&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(),&lt;/span&gt; DataSourceUtil
                        &lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;createAndConfigureDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;masterTenant&lt;span style=&quot;color: #333333&quot;&gt;));&lt;/span&gt;
            &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;dataSourcesMtApp&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;tenantIdentifier&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!-- End: Highlighted code --&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
The complete &lt;a href=&quot;https://github.com/sunitk/multitenancy-dynamic-tenant&quot; target=&quot;_blank&quot;&gt;source code&lt;/a&gt; is checked into GitHub. Its a standard Maven project which you can import into your IDE. 
&lt;br/&gt;&lt;br/&gt;
&lt;h2&gt;In conclusion&lt;/h2&gt;
That&#39;s all there is to reading tenant information at run time. For a production grade application, I recommend that you create a separate Spring Boot app or a microservice to manage the tenant information in the master_tenant table. So this keeps the management of the application separate from the actual application. The master database can be used to store other kinds of app related information and the separate app can be used by the administrators for other app related activities.
&lt;br/&gt;&lt;br/&gt;
Happy coding :)
&lt;br/&gt;&lt;br/&gt;
&lt;h2&gt;Update - 10 July 2018 &lt;/h2&gt;
A reader of my blog - Jordan Mackie - found an error which was a mistake on my part in publishing a small but important part of the code.
In the file TenantDatabaseConfig.java you need to explicitly name the tenant entity manager factory and use that when passing it in to the transaction manager.

So the code should look like
&lt;br/&gt;
&lt;!-- START HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;div style=&quot;background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;&quot;&gt;&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantTransactionManager&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;public&lt;/span&gt; JpaTransactionManager &lt;span style=&quot;color: #0066BB; font-weight: bold&quot;&gt;transactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold&quot;&gt;@Qualifier&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0&quot;&gt;&amp;quot;tenantEntityManagerFactory&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt;
EntityManagerFactory tenantEntityManager&lt;span style=&quot;color: #333333&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333&quot;&gt;{&lt;/span&gt;
        JpaTransactionManager transactionManager &lt;span style=&quot;color: #333333&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;new&lt;/span&gt; JpaTransactionManager&lt;span style=&quot;color: #333333&quot;&gt;();&lt;/span&gt;
        transactionManager&lt;span style=&quot;color: #333333&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000CC&quot;&gt;setEntityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333&quot;&gt;(&lt;/span&gt;tenantEntityManager&lt;span style=&quot;color: #333333&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold&quot;&gt;return&lt;/span&gt; transactionManager&lt;span style=&quot;color: #333333&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;!-- END HIGHLIGHTED CODE --&gt;
&lt;br/&gt;
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2018/05/adding-tenants-without-application.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0Ketc4dm9h0Hgq4HB2mPjdFTJJ3X1gxYhow42k3PVmPMEqhTfS55fJStEgUhtwAiEfLGMuA3tHG8xqIExIfkn4JdGCudJnb4hSY4qTpYbrgll5JdM1Sx3l4OuVrge7m4Ei2ZF9Wt9xj5k/s72-c/MTD-FIG-01.png" height="72" width="72"/><thr:total>175</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-546853038449403683</guid><pubDate>Thu, 10 May 2018 19:10:00 +0000</pubDate><atom:updated>2018-05-10T12:10:37.774-07:00</atom:updated><title>Spring Boot 2 generic JPA converter to serialize and deserialize an entity attribute as JSON</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
As I wrote in my &lt;a href=&quot;https://sunitkatkar.blogspot.com/2018/04/spring-boot-2-generic-jpa-converter-to.html&quot; target=&quot;_blank&quot;&gt;previous blog post&lt;/a&gt;, I needed to store some custom attributes of entities as JSON strings in the database. 
&lt;br /&gt;
&lt;br /&gt;
Sometimes an entity attribute is not just a native or simple type like a Date, Long or String. A Java POJO like structure is required as an attribute. One might argue that a separate entity should be created which results in a separate table and a reference to it should be used like in a OneToOne or ManyToOne or OneToMany type of relationship. But there are special business conditions where creating a separate entity is not feasible. So, storing this entity as a JSON string is a good solution.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Purpose of this blog post&lt;/h2&gt;
In the last blog post, I shared how I wrote a generic encryption decryption JPA Converter. In this blog post I will show you how to store a custom Java POJO like attribute as a JSON string in a database table column.
&lt;br /&gt;
&lt;br /&gt;
JPA allows writing &#39;conversion&#39; code so that an entity attribute (table column) can be converted from one type to another and back. Though this is not a latest feature of JPA nor a bleeding edge topic, I am sharing how I wrote a generic converter for serialization and serialization of a Java POJO object to a string type table column.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Java and JSON&lt;/h2&gt;
I am assuming you know what JSON is and how it is used for data transformation. If you need to know more then click &lt;a href=&quot;https://www.json.org/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;
In our case, we need to convert some Java POJO like JPA attribute to its JSON equivalent and store it in the database table column. Similarly, we need to parse the JSON format and convert it back to the original Java POJO like attribute.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Java and Jackson&lt;/h2&gt;
Given that JSON is not a complex format, one can attempt to convert a Java POJO like object into a JSON String and back by writing code for each such object. However, this is a tedious and error-prone endeavor. And why do it all yourself when there is a reliable, widely used library to do this? Faster Jackson is an awesome library to help convert your Java POJO like object into JSON (and XML too) and parse the JSON back into the original Java POJO object.
&lt;br /&gt;
&lt;br /&gt;
If you are new to Jackson or want to read more, then click &lt;a href=&quot;https://github.com/FasterXML/jackson&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. There is a good tutorial &lt;a href=&quot;https://www.tutorialspoint.com/jackson/index.htm&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. For a more Spring framework specific tutorial, click &lt;a href=&quot;https://springframework.guru/processing-json-jackson/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
JPA and Converter&lt;/h2&gt;
JPA allows you to apply a &lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/Convert.html&quot; target=&quot;_blank&quot;&gt;@Converter&lt;/a&gt; annotation to any Entity attribute i.e. to any table column definition in your table defintion. This is possible via the &lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/AttributeConverter.html&quot; target=&quot;_blank&quot;&gt;AttributeConveter&lt;/a&gt; interface. A class implementing this interface needs to implement the methods from this interface&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/AttributeConverter.html#convertToDatabaseColumn-X-&quot; target=&quot;_blank&quot;&gt;Y convertToDatabaseColumn(X attribute)&lt;/a&gt;&lt;/b&gt; -&amp;nbsp;Converts the value stored in the entity attribute into the data representation to be stored in the database.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/AttributeConverter.html#convertToEntityAttribute-Y-&quot; target=&quot;_blank&quot;&gt;X convertToEntityAttribute(Y dbData)&lt;/a&gt; &lt;/b&gt;-&amp;nbsp; Converts the data stored in the database column into the value to be stored in the entity attribute. Note that it is the responsibility of the converter writer to specify the correct dbData type for the corresponding column for use by the JDBC driver: i.e., persistence providers are not expected to do such type conversion.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;h2&gt;
Writing the generic converter&lt;/h2&gt;
Please keep these two Jackson JSON javadocs open in your browser so that you can refer to them while reading the code I am presenting. 
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Jackson &lt;a href=&quot;http://fasterxml.github.io/jackson-core/javadoc/2.9/&quot; target=&quot;_blank&quot;&gt;Core Javadocs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Jackson &lt;a href=&quot;http://fasterxml.github.io/jackson-databind/javadoc/2.9/&quot; target=&quot;_blank&quot;&gt;Databind Javadocs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
Though we do not need it for this converter, you can also look at the Jackson JSON &lt;a href=&quot;http://fasterxml.github.io/jackson-annotations/javadoc/2.9/&quot; target=&quot;_blank&quot;&gt;Annotation javadocs&lt;/a&gt; for more details. 
&lt;br /&gt;
&lt;br /&gt;
Note that for a good error free conversion of  your Java POJO like object, one of the requirements is to provide the class type information to the Jackson &lt;a href=&quot;http://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/ObjectMapper.html&quot; target=&quot;_blank&quot;&gt;ObjectMapper&lt;/a&gt;. It is not an absolute must, but having it is better. Also for a generic converter, it becomes quite essential to tell the converter about the Class type of the object.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
The generic JSON JPA converter code&lt;/h2&gt;
Here is the converter code. We just need one concrete class which can then be extended to convert a specific Java POJO like attribute.
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- START: HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;sunitkatkar&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;blogspot&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;converters&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.io.IOException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.AttributeConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.slf4j.Logger&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.annotation.JsonAutoDetect&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.annotation.JsonInclude.Include&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.core.JsonProcessingException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.databind.ObjectMapper&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.databind.ObjectReader&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.databind.ObjectWriter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * JPA converter class which converts any POJO like object to a JSON string and&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * stores it in the database table column. The JSON string contains the class&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * name of the POJO and its JSON format string. &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Note: An abstract class is not needed as this class takes care of all the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * JSON serialization and deserialization. You only need to extend this class so&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * that you can use your POJO class for conversion. The extended class should be&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * annotated with the {@literal @}Converter annotation&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; *         (https://sunitkatkar.blogspot.com/)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (May 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param &amp;lt;X&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;GenericJsonAttributeConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;X&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;implements&lt;/span&gt; AttributeConverter&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;X&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; Logger LOG &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; LoggerFactory
            &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getLogger&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;GenericJsonAttributeConverter&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * To &#39;write&#39; the attribute POJO as a JSON string&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; ObjectWriter writer&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * To &#39;read&#39; the JSON string and convert to the attribute POJO&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; ObjectReader reader&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Default constructor&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GenericJsonAttributeConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

        ObjectMapper mapper &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; ObjectMapper&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;// We want all keys in the key value pair JSON even if the key has no&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;// value&lt;/span&gt;
        mapper&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setSerializationInclusion&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Include&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;ALWAYS&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;//@formatter:off&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;// The mapper should be able to &#39;see&#39; the entity attributes (fields)&lt;/span&gt;
        mapper&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setVisibility&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;mapper&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getSerializationConfig&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt;
                &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getDefaultVisibilityChecker&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt;
                &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;withFieldVisibility&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;JsonAutoDetect&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;Visibility&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;ANY&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
                &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;withGetterVisibility&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;JsonAutoDetect&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;Visibility&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;NONE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
                &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;withIsGetterVisibility&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;JsonAutoDetect&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;Visibility&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;NONE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;//@@formatter:on&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;// We are wrapping the entity attribute in a class. See class for&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;// details.&lt;/span&gt;
        reader &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; mapper&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;reader&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;forType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;JsonTypeLike&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        writer &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; mapper&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;writer&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;forType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;JsonTypeLike&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/*&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * (non-Javadoc)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @see&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * javax.persistence.AttributeConverter#convertToDatabaseColumn(java.lang.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Object)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertToDatabaseColumn&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;X attribute&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;attribute &lt;span style=&quot;color: #333333;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                JsonTypeLike&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;X&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; wrapper &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; JsonTypeLike&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;X&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;(&lt;/span&gt;attribute&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
                        writer&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
                String value &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; writer&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;writeValueAsString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;wrapper&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; value&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;JsonProcessingException e&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Failed to serialize as object into JSON: {}&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; attribute&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
                    e&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;RuntimeException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;e&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/*&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * (non-Javadoc)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @see&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * javax.persistence.AttributeConverter#convertToEntityAttribute(java.lang.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Object)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; X &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertToEntityAttribute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String dbData&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dbData &lt;span style=&quot;color: #333333;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                JsonTypeLike&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;X&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; wrapper &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; reader&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;readValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dbData&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
                X obj &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; wrapper&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;readValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;reader&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; obj&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;IOException e&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Failed to deserialize as object from JSON: {}&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; dbData&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
                    e&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;RuntimeException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;e&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * The concrete type is needed for Jackson to serialize or deserialize. This&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * class is created to wrap the entity type &amp;amp;lt;Y&amp;amp;gt; so that the Jackson&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link ObjectReader#forType(Class)} and&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link ObjectWriter#forType(Class))} can be used to get the concrete type&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * of the attribute being serialized/deserialized.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param &amp;lt;Y&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;JsonTypeLike&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;Y&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;// For adding the type (class) of the entity in the generated JSON&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String entityType&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;// For the actual value which is obtained by reading or writing the JSON&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String entityValue&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;JsonTypeLike&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * Constructor which helps initialize the ObjectWriter by providing the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * concrete class type to the writer&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * @param obj&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * @param writer&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         */&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;JsonTypeLike&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Y obj&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; ObjectWriter writer&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #888888;&quot;&gt;// TODO: Need a better way to do type conversion and not get safety&lt;/span&gt;
            &lt;span style=&quot;color: #888888;&quot;&gt;// warning&lt;/span&gt;
            Class&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;Y&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; classType &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;((&lt;/span&gt;Class&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;Y&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;)&lt;/span&gt; obj&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getClass&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
            &lt;span style=&quot;color: #888888;&quot;&gt;// We are saving the class type as a string in entityType so that&lt;/span&gt;
            &lt;span style=&quot;color: #888888;&quot;&gt;// while reading&lt;/span&gt;
            &lt;span style=&quot;color: #888888;&quot;&gt;// back the JSON, the target Class type is known o the mapper.&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;entityType&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; obj&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getClass&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;

            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;entityValue&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; writer&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;forType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;classType&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
                        &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;writeValueAsString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;obj&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;JsonProcessingException e&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Failed serializing object to JSON: {}&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; obj&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; e&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * Read the JSON format string and create the target Java POJO object&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * @param reader&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;         */&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Y &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;readValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;ObjectReader reader&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                &lt;span style=&quot;color: #888888;&quot;&gt;// Once the json string is read, we need to know what is the&lt;/span&gt;
                &lt;span style=&quot;color: #888888;&quot;&gt;// destination class&lt;/span&gt;
                &lt;span style=&quot;color: #888888;&quot;&gt;// type. So reading the entityType value helps in getting the&lt;/span&gt;
                &lt;span style=&quot;color: #888888;&quot;&gt;// Class details.&lt;/span&gt;
                Class&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; clazz &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; Class&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;forName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;entityType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
                Y obj &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; reader&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;forType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;clazz&lt;span style=&quot;color: #333333;&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;readValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;entityValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; obj&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;ClassNotFoundException &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; IOException e&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Failed deserializing object from JSON: {}&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
                        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;entityValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; e&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getEntityType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; entityType&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setEntityType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String type&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;entityType&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; type&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getEntityValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; entityValue&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String value&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;entityValue&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; value&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- END: HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;h2&gt;
Example for using the converter&lt;/h2&gt;
Let us suppose there is a class called Student and it contains an attribute of another custom type called Course. The Course is a simple Java POJO which contains details about the course that a student enrolls in.
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
JPA Entity - Student&lt;/h3&gt;
This JPA entity has a Course attribute. The Student entity will create a table called &#39;student&#39; in the database and have a column/field called &#39;course&#39;. This course attribute is the one which needs to be stored as a JSON string.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- START: HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;sunitkatkar&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;blogspot&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Convert&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Entity&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.GeneratedValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.GenerationType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Id&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Table&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.core.JsonProcessingException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.databind.ObjectMapper&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.fasterxml.jackson.databind.ObjectWriter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.sunitkatkar.blogspot.converters.CourseJsonConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * JPA Entity which will be saved in the database table named &#39;student&#39;. The&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * attribute (or table column) &amp;lt;tt&amp;gt;course&amp;lt;/tt&amp;gt; needs to be converted to a JSON&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * string for storage and converted back to {@link Course} POJO when read.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; *         (https://sunitkatkar.blogspot.com/)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (May 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Entity&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Table&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;student&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Student&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Id&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@GeneratedValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;strategy &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; GenerationType&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;IDENTITY&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;student_id&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; Long id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;first_name&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String firstName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;last_name&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String lastName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * This attribute is the Course POJO which needs to be stored as a JSON&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * string&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Convert&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;converter &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; CourseJsonConverter&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;course&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; Course course&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Just a field to get the Course POJO as a JSON string and display on the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * UI&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String json&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the json&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Default constructor&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;Student&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;// Getters and setters&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the id&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Long &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param id&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the id to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Long id&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the firstName&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getFirstName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; firstName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param firstName&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the firstName to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setFirstName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String firstName&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;firstName&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; firstName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the lastName&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getLastName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; lastName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param lastName&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the lastName to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setLastName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String lastName&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;lastName&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; lastName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the course&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Course &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getCourse&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; course&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param course&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the course to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setCourse&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Course course&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;course&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; course&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Method to get the Course POJO as a JSON string for display on UI&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getJson&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        ObjectMapper mapper &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; ObjectMapper&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
        ObjectWriter writer &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; mapper&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;writer&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;forType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Course&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

        String jsonString &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            jsonString &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; writer&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;withDefaultPrettyPrinter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt;
                    &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;writeValueAsString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;course&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #888888;&quot;&gt;// System.out.println(jsonString);&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;JsonProcessingException e&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            e&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;printStackTrace&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; jsonString&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param json&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the json to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setJson&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String json&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;json&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; json&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- END: HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;h3&gt;
Course Java POJO&lt;/h3&gt;
This is the Course attribute in the Student JPA entity. Do note that when you use &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/util/Date.html&quot; target=&quot;_blank&quot;&gt;java.util.Date&lt;/a&gt; fields you must annotate them with a &lt;a href=&quot;https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/format/annotation/DateTimeFormat.html&quot; target=&quot;_blank&quot;&gt;@DateTimeFormat&lt;/a&gt; annotation so that Spring understands how to convert a string in a date like format to an actual date format. This is especially applicable when you have a browser based UI to enter dates.
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- START: HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;sunitkatkar&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;blogspot&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Date&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.format.annotation.DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * This POJO is a attribute of the {@link Student} entity. This will be&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * serialized as a JSON string and stored in the &#39;course&#39; field in the &#39;student&#39;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * table.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; *         (https://sunitkatkar.blogspot.com/)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (May 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Course&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; Long id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String title&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String description&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * The @DateTimeFormat annotation is required as the browser sends a date in&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * string format and Spring needs to translate it into a date. So we have to&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * specify a format for the date. Note that the browser always sends date in&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * the &#39;yyyy-MM-dd&#39; format when using the HTML5 attribute type=&#39;date&#39; on an&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &#39;input&#39; tag.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;pattern &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;yyyy-MM-dd&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; Date startDate&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;pattern &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;yyyy-MM-dd&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; Date endDate&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;Course&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the id&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Long &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param id&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the id to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Long id&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the title&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getTitle&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; title&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param title&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the title to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setTitle&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String title&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;title&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; title&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the description&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getDescription&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; description&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param description&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the description to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setDescription&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String description&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;description&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; description&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the startDate&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Date &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getStartDate&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; startDate&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param startDate&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the startDate to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setStartDate&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Date startDate&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;startDate&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; startDate&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return the endDate&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Date &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getEndDate&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; endDate&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param endDate&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            the endDate to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setEndDate&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Date endDate&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;endDate&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; endDate&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- END: HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;h3&gt;
Using the JSON JPA Converter&lt;/h3&gt;
To use the converter, all you need to do is create a class which extends from it. The following example is applicable for the Student entity and its attribute Course. That&#39;s all there is to it.
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- START: HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Converter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.sunitkatkar.blogspot.model.Course&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Concrete converter class which extends the {@link GenericJsonAttributeConverter}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * class. &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Note: No need to do anything here. This is used to pass the attribute type to&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * the GenericJsonAttributeConverter&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; *         (https://sunitkatkar.blogspot.com/)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (May 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Converter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;autoApply &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;CourseJsonConverter&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; GenericJsonAttributeConverter&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;Course&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- END: HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;h2&gt;
Resources&lt;/h2&gt;
I have included a complete working Spring Boot application to demonstrate how this JSON converter can be used. Visit my &lt;a href=&quot;https://github.com/sunitk/generic-jpa-converter-json&quot; target=&quot;_blank&quot;&gt;Github repository&lt;/a&gt; to download the code. You are free to fork it, but just request you to send me an email when you do so.
&lt;br /&gt;
&lt;br /&gt;
Happy coding :)

&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2018/05/spring-boot-2-generic-jpa-converter-to.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-2511881447837261037</guid><pubDate>Wed, 25 Apr 2018 21:45:00 +0000</pubDate><atom:updated>2018-05-10T12:11:15.245-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Attribute</category><category domain="http://www.blogger.com/atom/ns#">AttributeConverter</category><category domain="http://www.blogger.com/atom/ns#">Cipher</category><category domain="http://www.blogger.com/atom/ns#">Convert</category><category domain="http://www.blogger.com/atom/ns#">Converter</category><category domain="http://www.blogger.com/atom/ns#">crypto</category><category domain="http://www.blogger.com/atom/ns#">decrypt</category><category domain="http://www.blogger.com/atom/ns#">encrypt</category><category domain="http://www.blogger.com/atom/ns#">Entity</category><category domain="http://www.blogger.com/atom/ns#">HIbernate</category><category domain="http://www.blogger.com/atom/ns#">JPA</category><category domain="http://www.blogger.com/atom/ns#">Key</category><category domain="http://www.blogger.com/atom/ns#">Spring</category><title>Spring Boot 2 generic JPA converter to encrypt and decrypt an entity attribute</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
A recent requirement in my work mandated that certain columns in a table be encrypted when stored in the database. One can use the &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/javax/crypto/package-summary.html&quot; target=&quot;_blank&quot;&gt;javax.crypto package&lt;/a&gt; from the standard JDK to achieve this by writing service layer code to encrypt and decrypt data for each entity attribute (table column) that required it.&lt;br /&gt;
&lt;br /&gt;
The entire code-base is built using Spring Boot 2 and JPA (Hibernate), so I was looking for a way to achieve the encryption and decryption without having to write code for each entity attribute.&amp;nbsp; Well, there is such a feature provided by JPA called Converters which provide a way for you to write code once and then apply it to any required table attribute by way of a simple &lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/Convert.html&quot; target=&quot;_blank&quot;&gt;@Converter&lt;/a&gt; annotation.&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Purpose of this blog post&lt;/h2&gt;
JPA allows writing &#39;conversion&#39; code so that an entity attribute (table column) can be converted from one type to another and back. Though this is not a latest feature of JPA nor a bleeding edge topic, I am sharing how I wrote a generic converter for encryption and decryption of a string type table column.&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Java and Cryptography&lt;/h2&gt;
The humble JDK provides a very good cryptography package &lt;a href=&quot;http://javax.crypto/&quot;&gt;javax.crypto&lt;/a&gt;&amp;nbsp;which provides many facilities to do all things related to cryptography, one of which is to encrypt and decrypt data (or strings). I will not go into the details but just note here that the &lt;a href=&quot;http://javax.crypto.cipher/&quot;&gt;javax.crypto.Cipher&lt;/a&gt; class provides the functionality of a cryptographic cipher or algorithm for encryption and decryption.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
How does cryptography work?&lt;/h3&gt;
I am not a cryptography expert, but understand enough of it to apply it to the problem at hand. Basically I want to encrypt a String and write it to a table column in the database and then decrypt it after reading it so that the other layers in the application can use it.&lt;br /&gt;
&lt;br /&gt;
The crypto facilities basically use an ecryption/decryption algorithm to encrypt/decrypt the string and secure the data by applying a key value, which only you know, to encrpt/decrypt the data. That&#39;s it in a nutshell.&lt;br /&gt;
&lt;br /&gt;
For more details on how Java cryptography works please see &lt;a href=&quot;http://tutorials.jenkov.com/java-cryptography/index.html&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt; excellent tutorial&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
JPA and Converter&lt;/h2&gt;
JPA allows you to apply a &lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/Convert.html&quot; target=&quot;_blank&quot;&gt;@Converter&lt;/a&gt; annotation to any Entity attribute i.e. to any table column definition in your table defintion. This is possible via the &lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/AttributeConverter.html&quot; target=&quot;_blank&quot;&gt;AttributeConveter&lt;/a&gt; interface. A class implementing this interface needs to implement the methods from this interface&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/AttributeConverter.html#convertToDatabaseColumn-X-&quot; target=&quot;_blank&quot;&gt;Y convertToDatabaseColumn(X attribute)&lt;/a&gt;&lt;/b&gt; -&amp;nbsp;Converts the value stored in the entity attribute into the data representation to be stored in the database.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;https://docs.oracle.com/javaee/7/api/javax/persistence/AttributeConverter.html#convertToEntityAttribute-Y-&quot; target=&quot;_blank&quot;&gt;X convertToEntityAttribute(Y dbData)&lt;/a&gt; &lt;/b&gt;-&amp;nbsp; Converts the data stored in the database column into the value to be stored in the entity attribute. Note that it is the responsibility of the converter writer to specify the correct dbData type for the corresponding column for use by the JDBC driver: i.e., persistence providers are not expected to do such type conversion.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Writing the generic attribute converter&lt;/h2&gt;
I needed a converter which would essentially take a String type attribute and then encrypt it. So, the method &lt;span style=&quot;background-color: yellow;&quot;&gt;Y convertToDatabaseColumn(X attribute)&lt;/span&gt; method needed to take a string and return an encrypted version of it for storage.&lt;br /&gt;
&lt;br /&gt;
The converter also has to read the stored encrypted string&amp;nbsp; and return the decrypted version. So, the method&amp;nbsp; &lt;span style=&quot;background-color: yellow;&quot;&gt;X convertToEntityAttribute(Y dbData)&lt;/span&gt; needed to take the encrypted String, decrypt it and and return it to the other layers of the JPA mechanism.&lt;br /&gt;
&lt;br /&gt;
One thought that came naturally to mind, was that I didn&#39;t want to write code once again when the need arose to encrypt and decrypt some other type of attribute, say a Date or something else. So the base attribute converter had to have just enough code to perform the encryption and decryption of a String. (Note that we want to store the data as an encrypted String in the table column). The other task of converting the entity attribute type to a String and vice versa would have to be done outside this base class to allow flexibility to allow using any attribute entity type.&lt;br /&gt;
&lt;br /&gt;
With these points in mind, here is how I wrote this attribute converter.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Step 1 - Write the encryption and decryption code&lt;/h3&gt;
As noted before, use Java cryptography to achieve encryption and decryption. For this a Cipher instance is needed with all its properties set appropriately. Then it can be used for encryption and decryption.
&lt;br /&gt;
&lt;!-- HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.security.InvalidAlgorithmParameterException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.security.InvalidKeyException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.security.Key&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.security.NoSuchAlgorithmException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.security.spec.AlgorithmParameterSpec&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.crypto.Cipher&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.crypto.NoSuchPaddingException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.crypto.spec.IvParameterSpec&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.crypto.spec.SecretKeySpec&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Utility class to generate an instance of {@link javax.crypto.Cipher}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (Apr 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;CipherMaker&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; String CIPHER_INSTANCE_NAME &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;AES/CBC/PKCS5Padding&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; String SECRET_KEY_ALGORITHM &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;AES&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param encryptionMode&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            - decides whether to ecrypt or decrypt data. Values accepted:&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            {@link Cipher#ENCRYPT_MODE} for encryption and&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            {@link Cipher#DECRYPT_MODE} for decryption.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param key&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            - the key to use for encrypting or decrypting data. This can be a&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            simple String like &quot;MySecretKey&quot; or a more complex, hard to guess&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *            longer string&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @throws InvalidKeyException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @throws NoSuchPaddingException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @throws NoSuchAlgorithmException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @throws InvalidAlgorithmParameterException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @throws InvalidKeyException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @throws InvalidAlgorithmParameterException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Cipher &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;configureAndGetInstance&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;int&lt;/span&gt; encryptionMode&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String key&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throws&lt;/span&gt; InvalidKeyException&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; NoSuchPaddingException&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; 
            NoSuchAlgorithmException&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; InvalidAlgorithmParameterException&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; 
            InvalidKeyException&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; InvalidAlgorithmParameterException &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

        Cipher cipher &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; Cipher&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getInstance&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;CIPHER_INSTANCE_NAME&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        Key secretKey &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; SecretKeySpec&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;key&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getBytes&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(),&lt;/span&gt; SECRET_KEY_ALGORITHM&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[]&lt;/span&gt; ivBytes &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;cipher&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getBlockSize&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()];&lt;/span&gt;
        AlgorithmParameterSpec algorithmParameters &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; IvParameterSpec&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;ivBytes&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

        cipher&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;encryptionMode&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; secretKey&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; algorithmParameters&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; cipher&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- /HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Step 2 - Write the base attribute converter&amp;nbsp;&lt;/h3&gt;
As noted before, the attribute converter needs to encrypt and decrypt. So, the CipherMaker class above will be useful here. The source code comments are self-explanatory.
&lt;br /&gt;
&lt;!-- HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;static&lt;/span&gt; org&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;apache&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;commons&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;lang3&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;StringUtils&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;isNotEmpty&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.security.InvalidAlgorithmParameterException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.security.InvalidKeyException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.security.NoSuchAlgorithmException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Base64&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.crypto.BadPaddingException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.crypto.Cipher&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.crypto.IllegalBlockSizeException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.crypto.NoSuchPaddingException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.AttributeConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Abstract base class for implementing the JPA Attribute Converter which will&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * encrypt and decrypt an Entity attribute (table column)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (Apr 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param &amp;lt;X&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;abstract&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;AbstractEncryptDecryptConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;X&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;implements&lt;/span&gt; AttributeConverter&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;X&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * This is the key required for encryption/decryption. This is defined here&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * for example purpose. In production, this should come from a secure&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * location not accessible easily. In Spring Boot, one possible location is&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * the application.properties file. Though its not the most secure way, it&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * will keep this key out of the actual java code.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; String SECRET_ENCRYPTION_KEY &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;MySuperSecretKey&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/** CipherMaker is needed to configure and create instance of Cipher */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; CipherMaker cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Constructor&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param cipherMaker&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;AbstractEncryptDecryptConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;CipherMaker cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;cipherMaker&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Default constructor&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;AbstractEncryptDecryptConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; CipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/*&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * (non-Javadoc)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @see&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * javax.persistence.AttributeConverter#convertToDatabaseColumn(java.lang.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Object)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertToDatabaseColumn&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;X attribute&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;isNotEmpty&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;SECRET_ENCRYPTION_KEY&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; isNotNullOrEmpty&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;attribute&lt;span style=&quot;color: #333333;&quot;&gt;))&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
   &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    Cipher cipher &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;configureAndGetInstance&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;
      Cipher&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;ENCRYPT_MODE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; 
      SECRET_ENCRYPTION_KEY&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;encryptData&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;cipher&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; attribute&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;NoSuchAlgorithmException 
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; InvalidKeyException
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; InvalidAlgorithmParameterException 
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; BadPaddingException
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; NoSuchPaddingException 
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; IllegalBlockSizeException e&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;RuntimeException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;e&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
  &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertEntityAttributeToString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;attribute&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/*&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * (non-Javadoc)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @see&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * javax.persistence.AttributeConverter#convertToEntityAttribute(java.lang.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Object)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; X &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertToEntityAttribute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String dbData&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;isNotEmpty&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;SECRET_ENCRYPTION_KEY&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; isNotEmpty&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dbData&lt;span style=&quot;color: #333333;&quot;&gt;))&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
   &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    Cipher cipher &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;configureAndGetInstance&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;
      Cipher&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DECRYPT_MODE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; 
      SECRET_ENCRYPTION_KEY&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;decryptData&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;cipher&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; dbData&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;NoSuchAlgorithmException 
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; InvalidAlgorithmParameterException
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; InvalidKeyException 
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; BadPaddingException
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; NoSuchPaddingException 
     &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; IllegalBlockSizeException e&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;RuntimeException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;e&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
  &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertStringToEntityAttribute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dbData&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * The concrete class which implements this abstract class will have to&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * provide the implementation. For simple String encryption, the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * implementation is simple as apache commons lang StringUtils can be used.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * But this method was abstracted out as there might be other types of null&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * check technique required when a non String entity is to be encrypted&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param attribute&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;abstract&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;boolean&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;isNotNullOrEmpty&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;X attribute&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * The concrete class which implements this abstract class will have to&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * provide the implementation. For decryption of a String, its simple as a&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * String has to be returned, but for other non String types some more code&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * might have to be implemented. For example, a Date type of Date string.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param dbData&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;abstract&lt;/span&gt; X &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertStringToEntityAttribute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String dbData&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * The concrete class which implements this abstract class will have to&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * provide the implementation. For encryption of a String, its simple as a&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * String has to be returned, but for other non String types some more code&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * might have to be implemented. For example, a Date type of Date string.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param attribute&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;abstract&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertEntityAttributeToString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;X attribute&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Helper method to encrypt data&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param cipher&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param attribute&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @throws IllegalBlockSizeException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @throws BadPaddingException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;encryptData&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Cipher cipher&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; X attribute&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
   &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throws&lt;/span&gt; IllegalBlockSizeException&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; BadPaddingException &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[]&lt;/span&gt; bytesToEncrypt &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; convertEntityAttributeToString&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;attribute&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getBytes&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[]&lt;/span&gt; encryptedBytes &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; cipher&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;doFinal&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;bytesToEncrypt&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; Base64&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getEncoder&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;encodeToString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;encryptedBytes&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Helper method to decrypt data&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param cipher&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param dbData&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @throws IllegalBlockSizeException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @throws BadPaddingException&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; X &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;decryptData&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Cipher cipher&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String dbData&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
   &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throws&lt;/span&gt; IllegalBlockSizeException&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; BadPaddingException &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[]&lt;/span&gt; bytesToDecrypt &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; Base64&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getDecoder&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;decode&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dbData&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[]&lt;/span&gt; decryptedBytes &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; cipher&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;doFinal&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;bytesToDecrypt&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertStringToEntityAttribute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;decryptedBytes&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- /HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Step 3 - Implementing the concrete String encryption/descryption JPA attribute converter
&lt;/h3&gt;
Now that the base class and crypto code is ready, the actual implementation for writing a string ecnryption/decryption JPA converter is quite easy.
&lt;br /&gt;
&lt;!-- HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Concrete implementation of the {@link AbstractEncryptDecryptConverter}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * abstract class to encrypt/decrypt an entity attribute of type&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link java.lang.String} &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Note: This is the class where the {@literal @}Converter annotation is applied&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (Apr 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0 *&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Converter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;autoApply &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;StringEncryptDecryptConverter&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; AbstractEncryptDecryptConverter&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Default constructor initializes with an instance of the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * {@link CipherMaker} crypto class to get a {@link javax.crypto.Cipher}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * instance&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;StringEncryptDecryptConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; CipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Constructor&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param cipherMaker&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;StringEncryptDecryptConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;CipherMaker cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
 &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;boolean&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;isNotNullOrEmpty&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String attribute&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;isNotEmpty&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;attribute&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
 String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertStringToEntityAttribute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String dbData&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #888888;&quot;&gt;// the input is a string and output is a string&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; dbData&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
 String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertEntityAttributeToString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String attribute&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #888888;&quot;&gt;// Here too the input is a string and output is a string&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; attribute&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- /HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Step 4 - Using the String encryption/descryption JPA attribute converter&lt;/h3&gt;
Using this JPA converter in a JPA Entity is just a matter of annotating the attribute with the @Convert annotation as shown below.
&lt;br /&gt;
&lt;!-- HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.io.Serializable&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Convert&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Entity&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.GeneratedValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.GenerationType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Id&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Table&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * JPA Entity which will be saved in the database table named &#39;employee&#39;. The&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * attribute (or table column) &amp;lt;tt&amp;gt;sensitiveData&amp;lt;/tt&amp;gt; needs to be encrypted for&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * storage and decrypted when read.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (Apr 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param &amp;lt;X&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Entity&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Table&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;employee&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Employee&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;implements&lt;/span&gt; Serializable &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;long&lt;/span&gt; serialVersionUID &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1L&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Id&lt;/span&gt;
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@GeneratedValue&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;strategy &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; GenerationType&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;IDENTITY&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;employee_id&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; Long id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;first_name&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String firstName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;last_name&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String lastName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * This String attribute needs to be encrypted&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Column&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;sensitive_data&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Convert&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;converter &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; StringEncryptDecryptConverter&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String sensitiveData&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return the id&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Long &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param id&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  *            the id to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Long id&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; id&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return the firstName&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getFirstName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; firstName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param firstName&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  *            the firstName to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setFirstName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String firstName&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;firstName&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; firstName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return the lastName&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getLastName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; lastName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param lastName&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  *            the lastName to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setLastName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String lastName&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;lastName&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; lastName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return the sensitiveData&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getSensitiveData&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; sensitiveData&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @param sensitiveData&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  *            the sensitveData to set&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setSensitiveData&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String sensitiveData&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;sensitiveData&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; sensitiveData&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- /HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Bonus - Converter to encrypt / decrypt LocalDate&lt;/h2&gt;
Since the basic infrastructure for encrypting and decrypting JPA entity attributes is created, it can be used for converting other types of entities, for example, an attribute of type &lt;a href=&quot;http://java.time.localdate/&quot;&gt;java.time.LocalDate&lt;/a&gt;. Here is the code to do that.
&lt;br /&gt;
&lt;!-- HIGHLIGHTED CODE --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;static&lt;/span&gt; java&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;time&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DateTimeFormatter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;ISO_DATE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;static&lt;/span&gt; org&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;apache&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;commons&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;lang3&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;StringUtils&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.time.LocalDate&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.Converter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Concrete implementation of the {@link AbstractEncryptDecryptConverter}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * abstract class to encrypt/decrypt an entity attribute of type&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link java.time.LocalDate} &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Note: This is the class where the {@literal @}Converter annotation is applied&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar, sunitkatkar@gmail.com&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since ver 1.0 (Apr 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0 *&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Converter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;autoApply &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;LocalDateEncryptDecryptConverter&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; AbstractEncryptDecryptConverter&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;LocalDate&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;LocalDateEncryptDecryptConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; CipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;LocalDateEncryptDecryptConverter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;CipherMaker cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;cipherMaker&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
 &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;boolean&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;isNotNullOrEmpty&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;LocalDate attribute&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; attribute &lt;span style=&quot;color: #333333;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
 LocalDate &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertStringToEntityAttribute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String dbData&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dbData&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;?&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; LocalDate&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dbData&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; ISO_DATE&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
 String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;convertEntityAttributeToString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;LocalDate attribute&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;((&lt;/span&gt;attribute &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;?&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; attribute&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;ISO_DATE&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- /HIGHLIGHTED CODE --&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Resources&lt;/h3&gt;
The source code for this blog post is available as a Spring Boot 2 project on Github. Click &lt;a href=&quot;https://github.com/sunitk/generic-jpa-converter-encrypt-decrypt&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Happy coding :) 
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2018/04/spring-boot-2-generic-jpa-converter-to.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>12</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-7354205571276707034</guid><pubDate>Wed, 11 Apr 2018 16:29:00 +0000</pubDate><atom:updated>2018-04-11T16:36:47.017-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">HIbernate</category><category domain="http://www.blogger.com/atom/ns#">hikari cp</category><category domain="http://www.blogger.com/atom/ns#">jdbc</category><category domain="http://www.blogger.com/atom/ns#">JPA</category><category domain="http://www.blogger.com/atom/ns#">login form extra field</category><category domain="http://www.blogger.com/atom/ns#">multitenancy</category><category domain="http://www.blogger.com/atom/ns#">multitenant</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">ORM</category><category domain="http://www.blogger.com/atom/ns#">spring boot 2</category><category domain="http://www.blogger.com/atom/ns#">spring data</category><category domain="http://www.blogger.com/atom/ns#">spring security 5</category><category domain="http://www.blogger.com/atom/ns#">tenant per database</category><title>Building SaaS style multi-tenant web app with Spring Boot 2 and Spring Security 5 - Part 1</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Software as a Service or &lt;b&gt;SaaS&lt;/b&gt; has been around for quite some time now.&amp;nbsp; But most of the time, developers are building single tenant applications as per requirements.&amp;nbsp; These applications have just one database and one web server at their core.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;/h3&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Purpose of this blog post&lt;/h2&gt;
I wanted a solution where multi-tenancy is achieved by having a database per tenant and all user information (username, password, etc) for authentication and authorization stored in a user table in the respective tenant databases. It meant that not only did I need a multi-tenant application, but also a secure application like any other web application secured by Spring Security.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
I know how to use Spring Security to secure a web application and how to use Hibernate to connect to a database. The requirement further dictated that all users belonging to a tenant be stored in the tenant database and not a separate or central database. This would allow for complete data isolation for each tenant.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
So I did what most people do - I googled :)&amp;nbsp; I found many blog posts and articles published on multi-tenancy and web application security, but could not found a single solution or example implementation which addresses database per tenant approach &lt;b&gt;along&lt;/b&gt; &lt;b&gt;with&lt;/b&gt; security.&amp;nbsp; Maybe it is too trivial of a topic and hence no blogs or articles ;-)&lt;br /&gt;
&lt;br /&gt;
So I just built my own!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The solution I describe below might sound a little complicated but if you are familiar with the basics of Spring Security and Hibernate, then its quite simple, albeit a bit tedious.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;u&gt;I have broken up this blog post into two parts as the code to set up multi-tenancy and spring security is quite a lot. I don&#39;t want you to keep scrolling down to finish reading the blog post. :)&amp;nbsp;&lt;/u&gt; 
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
What is used to build the example in this blog post?&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Here, I am going to share how I built a SaaS style web app using the latest &lt;span style=&quot;background-color: yellow;&quot;&gt;Spring Boot 2, Spring JPA with Hibernate as the JPA provider to connect to MySQL and Spring Security 5 to secure the web aplication.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
What is Multi-Tenancy?&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
A multi-tenant application is where a tenant (i.e. users in a company) feels that the application has been created and deployed for them. In reality, there are many such tenants and they too are using the same application but get a feel that its built just for them. Typical examples are online applications for time-sheet management, project management, Scrum/Agile Sprint management, etc etc.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
A more technical explanation of multi-tenancy&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
SaaS applications are multi-tenant applications which require tenant data isolation in the database layer. There are different approaches for achieving this data isolation.&lt;br /&gt;
The most widely used approaches are&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;b&gt;Schema per tenant&lt;/b&gt; - all tenants have their own schema but these schema live in the same database&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Discriminator per tenant&lt;/b&gt; - data for all tenants is in the same schema in the database but is distinguished by a tenant discriminator column&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Database per tenant&lt;/b&gt; - each tenant has a separate database&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Which multi-tenancy approach is better?&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
There are many factors to consider before choosing a data isolation approach as mentioned above. We will not go into depth of each but focus mainly on building a multi-tenant application using the latest Spring Boot 2 framework along with JPA, Hibernate as the JPA provider and Spring Security 5.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Multi-tenancy using database per tenant approach&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
In many applications, especially in financial and medical domains, there is a strict need for absolute data isolation, security and privacy in multi-tenant applications. As far as my experience,&amp;nbsp; knowledge and research on this topic goes, multi-tenancy using database per tenant is the best for data isolation and security. I may be wrong and your feedback is welcome.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
How does the SaaS application work?&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;background-color: yellow;&quot;&gt;We will build a &lt;b&gt;database per tenant&lt;/b&gt; multi-tenant application secured by Spring Security.&lt;/span&gt;&lt;br /&gt;
In most SaaS applications, there is an entry point where a user belonging to a tenant enters the 
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;tenant name (company name in most cases or some other identifier)&lt;/li&gt;
&lt;li&gt;username&lt;/li&gt;
&lt;li&gt;password&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Step 1 - Process the login form with the extra &#39;tenant&#39; field&lt;/h4&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;The login form will present the tenant name, username and password to Spring Security for authentication.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The Spring Security&amp;nbsp;UsernamePasswordAuthenticationFilter filter intercepts the login form&#39;s request to the server. This filter needs to be extended so that the extra field &#39;tenant&#39; can be extracted.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;This tenant field is the tenant database identifier and is required by Hibernate to identify the tenant database to connect to.&lt;/li&gt;
&lt;li&gt;Once the tenant field is extracted by the security filter, it needs to be set in memory so that after the security filter is finished doing its job, this tenant identifier is available to the Hibernate code to connect to the correct tenant database.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;To make this happen, the tenant field is stored in a ThreadLocal&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Step 2 - Compare the login form values with existing user in the database&lt;/h4&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Now that the username, password and tenant values are available to Spring Security, the AbstractUserDetailsAuthenticationProvider&amp;nbsp;will use the retrieveUser() method to call upon the UserDetailsService&amp;nbsp;to get the user details from the database.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;If the credentials from the login form match those of the result returned by the tenant database, then the authentication is successful and Spring Security will now log the user into the application and create a secure session for the user for further access and interaction with the protected resources in the application.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Step 3 - Select the correct tenant database&lt;/h4&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Step 3 actually happens along side Step 2.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;It means that Spring Security does its job of preparing user credentials for comparison with existing users in the database.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;And Hibernate does its job of selecting the correct tenant database to provide such a user record to Spring Security for comparison.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;span class=&quot;tr_bq&quot; style=&quot;text-align: left;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;text-align: left;&quot;&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;span class=&quot;tr_bq&quot; style=&quot;text-align: left;&quot;&gt;
How does Step 3 work?&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;span class=&quot;tr_bq&quot; style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;In Step 2 above, Spring Security queries the database for a user based on the login form username and tenant field. So how does Hibernate know to get the user from the correct tenant database. In Step 1 note that the tenant field is stored in a ThreadLocal for later access.&amp;nbsp;&lt;/li&gt;
&lt;/span&gt;&lt;/ul&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;span class=&quot;tr_bq&quot; style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Hibernate provides&amp;nbsp;CurrentTenantIdentifierResolver for resolving or identifying the correct tenant id. The tenant id is extracted from the ThreadLocal storage.&lt;/li&gt;
&lt;/span&gt;&lt;/ul&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;span class=&quot;tr_bq&quot; style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Hibernate also provides&amp;nbsp;AbstractDataSourceBasedMultiTenantConnectionProviderImpl&amp;nbsp;(also see&amp;nbsp;DataSourceBasedMultiTenantConnectionProviderImpl) whose job is to provide the datasource corresponding to the tenant identifier.&lt;/li&gt;
&lt;/span&gt;&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;span class=&quot;tr_bq&quot; style=&quot;text-align: left;&quot;&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF5CqyiaQJNkPo7qbkA1Dr8TNheHTyXN9ATuXq1OvBz7WifDRUq8g2ebfW2psbpP3NYf778VRhiH-8nEDNvYH0X7gh3MmBmNHQPRSuMOXFlvN49H1chQDUxMXJlJY_WVHIErZAHsJVwH7z/s1600/FIG-01-A.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img alt=&quot;How Spring Security and Hibernate process the login form&quot; border=&quot;0&quot; data-original-height=&quot;353&quot; data-original-width=&quot;500&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF5CqyiaQJNkPo7qbkA1Dr8TNheHTyXN9ATuXq1OvBz7WifDRUq8g2ebfW2psbpP3NYf778VRhiH-8nEDNvYH0X7gh3MmBmNHQPRSuMOXFlvN49H1chQDUxMXJlJY_WVHIErZAHsJVwH7z/s1600/FIG-01-A.png&quot; title=&quot;How Spring Security and Hibernate process the login form&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;!--StartFragment--&gt;&lt;span style=&quot;font-size: small;&quot;&gt;How Spring Security and Hibernate process the login form&lt;/span&gt;&lt;!--EndFragment--&gt;

&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;How Spring Security and Hibernate process the login form&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Technology Stack&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
I am assuming that you are comfortable with Spring MVC, Spring Boot, JPA, Hibernate and Spring Security. The example application was built using - &lt;br /&gt;
&lt;ul&gt;&lt;span style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Spring Boot 2 (2.0.1.RELEASE)&lt;/li&gt;
&lt;li&gt;Spring Security 5&amp;nbsp;&lt;/li&gt;
&lt;li&gt;MySQL&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Spring JPA (Spring Boot 2 provides latest Hibernate 5 as the JPA provider)&lt;/li&gt;
&lt;li&gt;Java 8&lt;/li&gt;
&lt;li&gt;Spring STS IDE&lt;/li&gt;
&lt;/span&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;
Understanding the code for the application&lt;/span&gt;&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;I will describe the significant code in this section. Rest of the code is available in the GitHub repository&amp;nbsp;&lt;/span&gt;for this example application.&amp;nbsp; The link is in the Resources section at the end. If you want to just use the code and run it, then skip to the resources section at the end of part 2 for the GitHub link.&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;Project Layout&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;This is how my project layout is in &lt;a href=&quot;https://spring.io/tools/sts/all&quot; target=&quot;_blank&quot;&gt;Spring STS&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-hnk8vi-QuB2RiEAx2rl3xI-MTl8NUjj-7EHq9DBNm_VPm7HGxhwGHFqTnDe3XvLfrla9nvMQovmNcux1a0urbXCl5ZEMPLdCVMPmCh7Cta6XXUpslrWUiY-FUpSMcHbKSQUE1tqTAyiT/s1600/FIG-02-A.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1095&quot; data-original-width=&quot;500&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-hnk8vi-QuB2RiEAx2rl3xI-MTl8NUjj-7EHq9DBNm_VPm7HGxhwGHFqTnDe3XvLfrla9nvMQovmNcux1a0urbXCl5ZEMPLdCVMPmCh7Cta6XXUpslrWUiY-FUpSMcHbKSQUE1tqTAyiT/s1600/FIG-02-A.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File: pom.xml&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;Using the Spring Initialzr create a project with Spring Web, Security, Thymeleaf, MySQL and JPA. It should generate a pom.xml as follows:&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Note that I have added a few extra dependencies -&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Cyber NekoHTML for setting ThymeLeaf in legacy mode. Why? Thymeleaf complains if there are no proper closing tags but HTML5 allows some attributes to not have closing tags. So the fix is to use this dependency. A detailed problem statement and its solution is on &lt;a href=&quot;https://stackoverflow.com/questions/28624768/thymeleaf-strict-html-parsing-issue&quot; target=&quot;_blank&quot;&gt;this stackoverflow thread&lt;/a&gt;.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Apache &lt;a href=&quot;https://mvnrepository.com/artifact/org.apache.commons/commons-lang3&quot; target=&quot;_blank&quot;&gt;commons-lang-3&lt;/a&gt; for StringUtils&lt;/li&gt;
&lt;li&gt;&lt;div style=&quot;line-height: 16.25px;&quot;&gt;
&lt;a href=&quot;https://docs.spring.io/spring-boot/docs/current/reference/html/configuration-metadata.html&quot; target=&quot;_blank&quot;&gt;spring-boot-configuration-processor&lt;/a&gt; for helping with reading config properties. When you have annotations like @ConfigurationProperties, the STS IDE itself suggests that this dependency should be added.&lt;/div&gt;
&lt;/li&gt;
&lt;/span&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
This is the final pom.xml&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #bc7a00;&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;project&lt;/span&gt; &lt;span style=&quot;color: #7d9029;&quot;&gt;xmlns=&lt;/span&gt;&lt;span style=&quot;color: #ba2121;&quot;&gt;&quot;http://maven.apache.org/POM/4.0.0&quot;&lt;/span&gt;
 &lt;span style=&quot;color: #7d9029;&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span style=&quot;color: #ba2121;&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
 &lt;span style=&quot;color: #7d9029;&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span style=&quot;color: #ba2121;&quot;&gt;&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&lt;/span&gt;&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.example&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;multitenancy-mysql&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.1&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;jar&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;multitenancy-mysql&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Spring Boot JPA Hibernate with Per Database Multi-Tenancy with Spring Security&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;contributors&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;contributor&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Sunit Katkar&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;email&amp;gt;&lt;/span&gt;sunitkatkar@gmail.com&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/email&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://sunitkatkar.blogspot.com/&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/contributor&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/contributors&amp;gt;&lt;/span&gt;

 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;parent&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-parent&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0.1.RELEASE&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;relativePath&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt;&amp;lt;!-- lookup parent from repository --&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/parent&amp;gt;&lt;/span&gt;

 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;project.reporting.outputEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/project.reporting.outputEncoding&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;java.version&amp;gt;&lt;/span&gt;1.8&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/java.version&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-data-jpa&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-security&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-thymeleaf&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-web&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-configuration-processor&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;optional&amp;gt;&lt;/span&gt;true&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/optional&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;mysql&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;mysql-connector-java&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-test&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.security&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-security-test&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;net.sourceforge.nekohtml&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;nekohtml&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.9.21&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt;&amp;lt;!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.commons&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;commons-lang3&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.7&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;

 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-maven-plugin&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
 &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;
&lt;!-- END HTML generated by hilite.me --&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File: application.yml&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
I have worked mostly with application.properties files, but found that the YAML format is easier to use when defining multiple data sources. In this example application, I have defined two data sources &lt;span style=&quot;background-color: yellow;&quot;&gt;multitenancy.mtapp.dataSources&lt;/span&gt; which are pointing to 2 MySQL databases running on a MySQL instance.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;spring:
  thymeleaf:
    cache: false
    mode: LEGACYHTML5
  jpa:
    database: mysql
    show-sql: true 
    generate-ddl: false
    hibernate: 
      ddl-auto: none  

multitenancy: 
  mtapp: 
    dataSources: 
      -
        tenantId: tenant_1 
        url: jdbc:mysql://localhost:3306/dbtenant1?useSSL=false 
        username: tenant1 
        password: admin123 
        driverClassName: com.mysql.jdbc.Driver 
      -
        tenantId: tenant_2
        url: jdbc:mysql://localhost:3306/dbtenant2?useSSL=false
        username: tenant1
        password: admin123
        driverClassName: com.mysql.jdbc.Driver        
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- END HTML generated by hilite.me --&gt;

&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Note that &lt;span style=&quot;background-color: yellow;&quot;&gt;spring.thymeleaf.mode&lt;/span&gt; is set to LEGACYHTML5. The Cyber NekoHTML dependency will then take care of &lt;a href=&quot;https://stackoverflow.com/questions/28624768/thymeleaf-strict-html-parsing-issue&quot; target=&quot;_blank&quot;&gt;not being so strict about parsing HTML5&lt;/a&gt; and ThymeLeaf will not complain.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File: CustomUserDetails.java&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Note that Spring Security provides the interface &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/core/userdetails/UserDetails.html&quot; target=&quot;_blank&quot;&gt;UserDetails&lt;/a&gt;. An implementation of this interface&amp;nbsp;requires details about the user to be authenticated. For this, Spring Security provides a &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/core/userdetails/User.html&quot; target=&quot;_blank&quot;&gt;User&lt;/a&gt; class which can be used as is or extended. The example application extends this &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/core/userdetails/User.html&quot; target=&quot;_blank&quot;&gt;org.springframework.security.core.userdetails.User&lt;/a&gt; class to add the tenant attribute to the User.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;

&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Collection&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.core.GrantedAuthority&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * CustomUserDetails class extends the Spring Security provided&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link org.springframework.security.core.userdetails.User} class for&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * authentication purpose. Do not confuse this with the {@link User} class which&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * is an entity for storing application specific user details like username,&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * password, tenant, etc in the database using the JPA {@literal @}Entity&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * annotation.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; *&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;CustomUserDetails&lt;/span&gt; 
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; org&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;springframework&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;security&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;core&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;userdetails&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;User&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;long&lt;/span&gt; serialVersionUID &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1L&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * The extra field in the login form is for the tenant name&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String tenant&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Constructor based on the spring security User class but with an extra&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * argument &amp;lt;code&amp;gt;tenant&amp;lt;/code&amp;gt; to store the tenant name submitted by the end&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * user.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param username&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param password&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param authorities&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param tenant&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;CustomUserDetails&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String username&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String password&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; 
                Collection&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; GrantedAuthority&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; authorities&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
                String tenant&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;username&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; password&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; authorities&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;tenant&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; tenant&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;// Getters and Setters&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getTenant&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; tenant&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setTenant&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String tenant&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;tenant&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; tenant&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- END HTML generated by hilite.me --&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File:&amp;nbsp;CustomUserDetailsServiceImpl.java&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Spring Security provides a interface &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/core/userdetails/UserDetailsService.html&quot; target=&quot;_blank&quot;&gt;UserDetailsService&lt;/a&gt; which has just one method declared in it - &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/core/userdetails/UserDetailsService.html#loadUserByUsername-java.lang.String-&quot; target=&quot;_blank&quot;&gt;loadUserByUsername&lt;/a&gt;&amp;nbsp;which returns the &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/core/userdetails/UserDetails.html&quot; target=&quot;_blank&quot;&gt;UserDetails&lt;/a&gt;.&amp;nbsp; Now this UserDetails is used for authentication. In the example application code, the CustomUserDetails already defines the attributes for the User.
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;

&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;security&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.HashSet&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Set&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.apache.commons.lang3.StringUtils&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.core.GrantedAuthority&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.core.authority.SimpleGrantedAuthority&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.core.userdetails.UserDetails&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.core.userdetails.UsernameNotFoundException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.stereotype.Service&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.example.model.CustomUserDetails&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.example.model.Role&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.example.model.User&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.example.service.UserService&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link CustomUserDetailsService} contract defines a single method called&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * loadUserByUsernameAndTenantname.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * The {@link CustomUserDetailsServiceImpl} class simply implements the contract&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * and delegates to {@link UserService} to get the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link com.example.model.User} from the database so that it can be compared&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * with the {@link org.springframework.security.core.userdetails.User} for&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * authentication. Authentication occurs via the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link CustomUserDetailsAuthenticationProvider}.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; *&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Service&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;userDetailsService&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;CustomUserDetailsServiceImpl&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;implements&lt;/span&gt; CustomUserDetailsService &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; UserService userService&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; UserDetails &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;loadUserByUsernameAndTenantname&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String username&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String tenant&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throws&lt;/span&gt; UsernameNotFoundException &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;StringUtils&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;isAnyBlank&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;username&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; tenant&lt;span style=&quot;color: #333333;&quot;&gt;))&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;UsernameNotFoundException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Username and domain must be provided&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;// Look for the user based on the username and tenant by accessing the&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;// UserRepository via the UserService&lt;/span&gt;
        User user &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; userService&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;findByUsernameAndTenantname&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;username&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; tenant&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;user &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;UsernameNotFoundException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;
                    String&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Username not found for domain, &quot;&lt;/span&gt;
                            &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;username=%s, tenant=%s&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; username&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; tenant&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        Set&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;GrantedAuthority&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; grantedAuthorities &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; HashSet&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Role role &lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; user&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getRoles&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;())&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            grantedAuthorities&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; SimpleGrantedAuthority&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;role&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getRole&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()));&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        CustomUserDetails customUserDetails &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; 
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;CustomUserDetails&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;user&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getUsername&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(),&lt;/span&gt; 
                        user&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getPassword&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(),&lt;/span&gt; grantedAuthorities&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; tenant&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; customUserDetails&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- END HTML generated by hilite.me --&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File:&amp;nbsp;CustomUserDetailsAuthenticationProvider.java&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Spring Security provides class &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.html&quot; target=&quot;_blank&quot;&gt;AbstractUserDetailsAuthenticationProvider&lt;/a&gt; which&amp;nbsp;allows subclasses to override and work with &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/core/userdetails/UserDetails.html&quot; target=&quot;_blank&quot;&gt;UserDetails&lt;/a&gt; objects. The class is designed to respond to &lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/authentication/UsernamePasswordAuthenticationToken.html&quot; target=&quot;_blank&quot;&gt;UsernamePasswordAuthenticationToken&lt;/a&gt; authentication requests.&lt;br /&gt;
&lt;br /&gt;
The CustomUserDetailsAuthenticationProvider implemented for this application delegates to the&amp;nbsp;CustomUserDetailsService (implemented by&amp;nbsp;CustomUserDetailsServiceImpl) for retrieving the UserDetails for authentication
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;security&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.authentication.BadCredentialsException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.authentication.InternalAuthenticationServiceException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.authentication.UsernamePasswordAuthenticationToken&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.core.AuthenticationException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.core.userdetails.UserDetails&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.core.userdetails.UsernameNotFoundException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.security.crypto.password.PasswordEncoder&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.util.Assert&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link CustomUserDetailsAuthenticationProvider} extends&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link AbstractUserDetailsAuthenticationProvider} and delegates to the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link CustomUserDetailService} to retrieve the User. The most important&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * feature of this class is the implementation of the &amp;lt;code&amp;gt;retrieveUser&amp;lt;/code&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * method.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Note that the authentication token must be cast to CustomAuthenticationToken&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * to access the custom field - tenant&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;CustomUserDetailsAuthenticationProvider&lt;/span&gt; 
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; AbstractUserDetailsAuthenticationProvider &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * The plaintext password used to perform PasswordEncoder#matches(CharSequence,&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * String)} on when the user is not found to avoid SEC-2056&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * (https://github.com/spring-projects/spring-security/issues/2280).&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; String USER_NOT_FOUND_PASSWORD &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;userNotFoundPassword&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * For encoding and/or matching the encrypted password stored in the database&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * with the user submitted password&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; PasswordEncoder passwordEncoder&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; CustomUserDetailsService userDetailsService&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * The password used to perform&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link PasswordEncoder#matches(CharSequence, String)} on when the user is not&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * found to avoid SEC-2056. This is necessary, because some&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link PasswordEncoder} implementations will short circuit if the password is&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * not in a valid format.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String userNotFoundEncodedPassword&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;CustomUserDetailsAuthenticationProvider&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;PasswordEncoder passwordEncoder&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            CustomUserDetailsService userDetailsService&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;passwordEncoder&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; passwordEncoder&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;userDetailsService&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; userDetailsService&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/*&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * (non-Javadoc)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @see org.springframework.security.authentication.dao.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * AbstractUserDetailsAuthenticationProvider#additionalAuthenticationChecks(org.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * springframework.security.core.userdetails.UserDetails,&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * org.springframework.security.authentication.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * UsernamePasswordAuthenticationToken)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;additionalAuthenticationChecks&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;UserDetails userDetails&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            UsernamePasswordAuthenticationToken authentication&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throws&lt;/span&gt; AuthenticationException &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;authentication&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getCredentials&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            logger&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;debug&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Authentication failed: no credentials provided&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;BadCredentialsException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;
                    messages&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getMessage&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;AbstractUserDetailsAuthenticationProvider.badCredentials&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; 
                            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Bad credentials&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;// Get the password submitted by the end user&lt;/span&gt;
        String presentedPassword &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; authentication&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getCredentials&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;toString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;// If the password stored in the database and the user submitted password do not&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;// match, then signal a login error&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(!&lt;/span&gt;passwordEncoder&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;matches&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;presentedPassword&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; userDetails&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getPassword&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()))&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            logger&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;debug&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Authentication failed: password does not match stored value&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;BadCredentialsException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;
                    messages&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getMessage&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;AbstractUserDetailsAuthenticationProvider.badCredentials&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; 
                            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Bad credentials&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;doAfterPropertiesSet&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throws&lt;/span&gt; Exception &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        Assert&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;notNull&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;userDetailsService&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;A UserDetailsService must be set&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;userNotFoundEncodedPassword&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;passwordEncoder&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;encode&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;USER_NOT_FOUND_PASSWORD&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/*&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * (non-Javadoc)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @see org.springframework.security.authentication.dao.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * AbstractUserDetailsAuthenticationProvider#retrieveUser(java.lang.String,&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * org.springframework.security.authentication.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * UsernamePasswordAuthenticationToken)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;protected&lt;/span&gt; UserDetails &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;retrieveUser&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String username&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; UsernamePasswordAuthenticationToken authentication&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throws&lt;/span&gt; AuthenticationException &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        CustomAuthenticationToken auth &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;CustomAuthenticationToken&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; authentication&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        UserDetails loadedUser&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            loadedUser &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;userDetailsService&lt;/span&gt;
                    &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;loadUserByUsernameAndTenantname&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;auth&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getPrincipal&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;toString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(),&lt;/span&gt;
                            auth&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getTenant&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;UsernameNotFoundException notFound&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;authentication&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getCredentials&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                String presentedPassword &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; authentication&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getCredentials&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;toString&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
                passwordEncoder&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;matches&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;presentedPassword&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; userNotFoundEncodedPassword&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; notFound&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Exception repositoryProblem&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;InternalAuthenticationServiceException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;repositoryProblem&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getMessage&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(),&lt;/span&gt; 
                    repositoryProblem&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;loadedUser &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;InternalAuthenticationServiceException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;
                    &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;UserDetailsService returned null, &quot;&lt;/span&gt;
                    &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;which is an interface contract violation&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; loadedUser&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- END HTML generated by hilite.me --&gt;

&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Conclusion of Part 1&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
In this part of the blog post, I have explained how this application works, how to set up your project, how Spring Security is set up.&lt;br /&gt;
&lt;br /&gt;
In the next part, I will show how the JPA and Hibernate part of the code is set up. Also I will show how Spring Security is tied in with the multi-tenancy Hibernate code.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://sunitkatkar.blogspot.com/2018/04/building-saas-style-multi-tenant-web2.html&quot; target=&quot;_blank&quot;&gt;Part 2&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2018/04/building-saas-style-multi-tenant-web.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF5CqyiaQJNkPo7qbkA1Dr8TNheHTyXN9ATuXq1OvBz7WifDRUq8g2ebfW2psbpP3NYf778VRhiH-8nEDNvYH0X7gh3MmBmNHQPRSuMOXFlvN49H1chQDUxMXJlJY_WVHIErZAHsJVwH7z/s72-c/FIG-01-A.png" height="72" width="72"/><thr:total>19</thr:total><georss:featurename>San Francisco Bay Area, CA, USA</georss:featurename><georss:point>37.8271784 -122.29130780000003</georss:point><georss:box>34.6193554 -127.45488180000002 41.0350014 -117.12773380000003</georss:box></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-1500022766436365484</guid><pubDate>Wed, 11 Apr 2018 04:10:00 +0000</pubDate><atom:updated>2018-04-11T16:41:08.061-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">HIbernate</category><category domain="http://www.blogger.com/atom/ns#">login form extra field</category><category domain="http://www.blogger.com/atom/ns#">multitenancy</category><category domain="http://www.blogger.com/atom/ns#">multitenant</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">ORM</category><category domain="http://www.blogger.com/atom/ns#">SaaS</category><category domain="http://www.blogger.com/atom/ns#">spring boot 2</category><category domain="http://www.blogger.com/atom/ns#">spring JPA</category><category domain="http://www.blogger.com/atom/ns#">spring security 5</category><title>Building SaaS style multi-tenant web app with Spring Boot 2 and Spring Security 5 - Part 2</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Continuing from part 1&lt;/h2&gt;
&lt;br /&gt;
In &lt;a href=&quot;https://sunitkatkar.blogspot.com/2018/04/building-saas-style-multi-tenant-web.html&quot; target=&quot;_blank&quot;&gt;part 1 of this blog post&lt;/a&gt;, I shared how you can build a SaaS style multi-tenant web application and how it works.&lt;br /&gt;
&lt;br /&gt;
In this part of the blog post, I will continue to show how to set up multi-tenant database access to the tenant databases using Spring JPA and Hibernate. Also how Spring Security is tied into all of this.&lt;/div&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Multi-Tenancy data access and tenant database selection&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
In multi-tenant setup,&amp;nbsp; Hibernate requires a datasource to be fed so that it can establish a connection/session with the database defined by the datasource.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Data access&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
For a multi-tenancy setup, Hibernate provides two facilities -&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.jboss.org/hibernate/orm/5.1/javadocs/org/hibernate/context/spi/CurrentTenantIdentifierResolver.html&quot; target=&quot;_blank&quot;&gt;CurrentTenantIdentifierResolver&lt;/a&gt; - an interface which should be implemented by the application code to identify the tenant&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.jboss.org/hibernate/orm/5.1/javadocs/org/hibernate/engine/jdbc/connections/spi/AbstractDataSourceBasedMultiTenantConnectionProviderImpl.html&quot; target=&quot;_blank&quot;&gt;AbstractDataSourceBasedMultiTenantConnectionProviderImpl&lt;/a&gt; - an abstract class which provides support for providing the correct datasource based on the tenant id to Hibernate&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Tenant identification and data source selection&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
In part 1 of the blog I had written that the tenant identifier is provided by the end user via the login form. The application code needs to parse this tenant field in the Spring Security layer and store it for tenant id resolution.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Spring provides a&amp;nbsp;&lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/api/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.html&quot; target=&quot;_blank&quot;&gt;UsernamePasswordAuthenticationFilter&lt;/a&gt; which is extended by the example application to retrieve the tenant value from the login form. This tenant value is stored in a ThreadLocal variable so that it can be used by the CurrentTenantIdentifierResolver implementation.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Understanding the code used in the application&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
I will explain the significant pieces of code in this part of the blog post so that you can follow how it is all related and how it all works.&lt;/div&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File:&amp;nbsp;MultitenancyProperties.java&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
As shown in part 1, the application.yml defines the data sources for the tenant databases. These should be available to the application code. MultitenancyProperties class has the&amp;nbsp;&lt;span style=&quot;background-color: yellow;&quot;&gt;@ConfigurationProperties&lt;/span&gt; annotation and is asked to parse the properties under the &lt;span style=&quot;background-color: yellow;&quot;&gt;multitenancy.app&lt;/span&gt; node from application.yml file.&lt;/div&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;multitenancy&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.List&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.context.properties.ConfigurationProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * This class reads the &amp;lt;code&amp;gt;multitenancy.mtapp&amp;lt;/code&amp;gt; node from&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &amp;lt;code&amp;gt;application.yml&amp;lt;/code&amp;gt; file and populates a list of&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link org.springframework.boot.autoconfigure.jdbc.DataSourceProperties}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * objects, with each instance containing the data source details about the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * database like url, username, password etc&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0 &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Configuration&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@ConfigurationProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;multitenancy.mtapp&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;MultitenancyProperties&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;DataSourceProperties&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; dataSourcesProps&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;DataSourceProperties&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getDataSources&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;dataSourcesProps&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setDataSources&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;DataSourceProperties&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; dataSourcesProps&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;dataSourcesProps&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; dataSourcesProps&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;DataSourceProperties&lt;/span&gt; 
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; org&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;springframework&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;boot&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;autoconfigure&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;jdbc&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DataSourceProperties&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; String tenantId&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getTenantId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; tenantId&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setTenantId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String tenantId&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;tenantId&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; tenantId&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- End code highlighted by hilite.me --&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File:&amp;nbsp;MultiTenancyJpaConfiguration.java&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Hibernate needs to be fed with the datasource that it should connect to. MultiTenancyJpaConfiguration reads the data sources from MultitenancyProperties and creates a map of the data sources. This map is then used for selecting the required tenant database based on the tenant identifier and Hibernate establishes a connection with that database.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;multitenancy&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.HashMap&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.LinkedHashMap&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Map&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.persistence.EntityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.sql.DataSource&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.hibernate.MultiTenancyStrategy&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.hibernate.cfg.Environment&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.hibernate.context.spi.CurrentTenantIdentifierResolver&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.autoconfigure.orm.jpa.JpaProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.context.properties.EnableConfigurationProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.jdbc.DataSourceBuilder&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.context.annotation.Primary&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.orm.jpa.JpaTransactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.transaction.PlatformTransactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.transaction.annotation.EnableTransactionManagement&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.example.model.Employee&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.example.multitenancy.MultitenancyProperties.DataSourceProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * This class defines the data sources to be used for accessing the different&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * databases (one database per tenant). It generates the Hibernate session and&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * entity bean for database access via Spring JPA as well as the Transaction&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * manager to be used.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Configuration&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@EnableConfigurationProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;({&lt;/span&gt; MultitenancyProperties&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; JpaProperties&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;})&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@EnableTransactionManagement&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;MultiTenancyJpaConfiguration&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; JpaProperties jpaProperties&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; MultitenancyProperties multitenancyProperties&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Builds a map of all data sources defined the application.yml file&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Primary&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Bean&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;name &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;dataSourcesMtApp&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; DataSource&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; dataSourcesMtApp&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; DataSource&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; result &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; HashMap&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;DataSourceProperties dsProperties &lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;multitenancyProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getDataSources&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;())&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            
            DataSourceBuilder factory &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; DataSourceBuilder&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt;
                    &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dsProperties&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getUrl&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;())&lt;/span&gt;
                    &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;username&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dsProperties&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getUsername&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;())&lt;/span&gt;
                    &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;password&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dsProperties&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getPassword&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;())&lt;/span&gt;
                    &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;driverClassName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dsProperties&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getDriverClassName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
            
            result&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;dsProperties&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getTenantId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(),&lt;/span&gt; factory&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; result&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Autowires the data sources so that they can be used by the Spring JPA to&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * access the database&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Bean&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; MultiTenantConnectionProvider &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;multiTenantConnectionProvider&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #888888;&quot;&gt;// Autowires dataSourcesMtApp&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;DataSourceBasedMultiTenantConnectionProviderImpl&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Since this is a multi-tenant application, Hibernate requires that the current&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * tenant identifier is resolved for use with&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link org.hibernate.context.spi.CurrentSessionContext} and&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link org.hibernate.SessionFactory#getCurrentSession()}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Bean&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; CurrentTenantIdentifierResolver &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;currentTenantIdentifierResolver&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;CurrentTenantIdentifierResolverImpl&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * org.springframework.beans.factory.FactoryBean that creates a JPA&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link javax.persistence.EntityManagerFactory} according to JPA&#39;s standard&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * container bootstrap contract. This is the most powerful way to set up a&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * shared JPA EntityManagerFactory in a Spring application context; the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * EntityManagerFactory can then be passed to JPA-based DAOs via dependency&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * injection. Note that switching to a JNDI lookup or to a&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link org.springframework.orm.jpa.LocalEntityManagerFactoryBean} definition&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * is just a matter of configuration!&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param multiTenantConnectionProvider&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param currentTenantIdentifierResolver&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Bean&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; LocalContainerEntityManagerFactoryBean &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;entityManagerFactoryBean&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;
            MultiTenantConnectionProvider multiTenantConnectionProvider&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            CurrentTenantIdentifierResolver currentTenantIdentifierResolver&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

        Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; Object&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; hibernateProps &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; LinkedHashMap&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        hibernateProps&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;putAll&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;jpaProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getProperties&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
        hibernateProps&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Environment&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;MULTI_TENANT&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; MultiTenancyStrategy&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DATABASE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        hibernateProps&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Environment&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;MULTI_TENANT_CONNECTION_PROVIDER&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; multiTenantConnectionProvider&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;&lt;/pre&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;        hibernateProps&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;put&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Environment&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;MULTI_TENANT_IDENTIFIER_RESOLVER&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; currentTenantIdentifierResolver&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #888888;&quot;&gt;// No dataSource is set to resulting entityManagerFactoryBean&lt;/span&gt;
        LocalContainerEntityManagerFactoryBean result &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; LocalContainerEntityManagerFactoryBean&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
        result&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setPackagesToScan&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;[]&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt; Employee&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getPackage&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;});&lt;/span&gt;
        result&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setJpaVendorAdapter&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; HibernateJpaVendorAdapter&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
        result&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setJpaPropertyMap&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;hibernateProps&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; result&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Interface used to interact with the entity manager factory for the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * persistence unit.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param entityManagerFactoryBean&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Bean&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; EntityManagerFactory &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;entityManagerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;LocalContainerEntityManagerFactoryBean 
            entityManagerFactoryBean&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; entityManagerFactoryBean&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getObject&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Creates a new&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link org.springframework.orm.jpa.JpaTransactionManager#JpaTransactionManager(EntityManagerFactory emf)}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * instance.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * {@link org.springframework.transaction.PlatformTransactionManager} is the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * central interface in Spring&#39;s transaction infrastructure. Applications can&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * use this directly, but it is not primarily meant as API: Typically,&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * applications will work with either TransactionTemplate or declarative&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * transaction demarcation through AOP.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param entityManagerFactory&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Bean&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; PlatformTransactionManager &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;transactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;EntityManagerFactory entityManagerFactory&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;JpaTransactionManager&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;entityManagerFactory&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- End code highlighted by hilite.me --&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File:&amp;nbsp;DataSourceBasedMultiTenantConnectionProviderImpl.java&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Hibernate provides&amp;nbsp;&lt;a href=&quot;https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/engine/jdbc/connections/spi/AbstractDataSourceBasedMultiTenantConnectionProviderImpl.html&quot; target=&quot;_blank&quot;&gt;AbstractDataSourceBasedMultiTenantConnectionProviderImpl&lt;/a&gt; which provides support for connections in a multi-tenant setup like the example application.
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
DataSourceBasedMultiTenantConnectionProviderImpl extends the abstract class and implements the selectDataSource() and selectAnyDataSource() methods.&amp;nbsp; &lt;span style=&quot;background-color: yellow;&quot;&gt;This class basically does the job of selecting the correct database based on the tenant id&lt;/span&gt; found by the tenant id resolver, which I will show next.&lt;/div&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;multitenancy&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Map&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.sql.DataSource&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * This class does the job of selecting the correct database based on the tenant&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * id found by the {@link CurrentTenantIdentifierResolverImpl}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Component&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;DataSourceBasedMultiTenantConnectionProviderImpl&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; AbstractDataSourceBasedMultiTenantConnectionProviderImpl &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;long&lt;/span&gt; serialVersionUID &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1L&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; DataSource&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; dataSourcesMtApp&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/*&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * (non-Javadoc)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @see org.hibernate.engine.jdbc.connections.spi.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * AbstractDataSourceBasedMultiTenantConnectionProviderImpl#selectAnyDataSource(&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * )&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;protected&lt;/span&gt; DataSource &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;selectAnyDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;dataSourcesMtApp&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;iterator&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #888888;&quot;&gt;/*&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * (non-Javadoc)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @see org.hibernate.engine.jdbc.connections.spi.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * AbstractDataSourceBasedMultiTenantConnectionProviderImpl#selectDataSource(&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * java.lang.String)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;protected&lt;/span&gt; DataSource &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;selectDataSource&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String tenantIdentifier&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;dataSourcesMtApp&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;tenantIdentifier&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- End code highlighted by hilite.me --&gt;

&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File:&amp;nbsp;&amp;nbsp;CurrentTenantIdentifierResolverImpl.java&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
This class does the job of identifying the tenant. In the example application the tenant id is stored in a ThreadLocal variable which is accessed in this class and provided to Hibernate&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0px;&quot;&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; com&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0000cc;&quot;&gt;multitenancy&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;

&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0e84b5; font-weight: bold;&quot;&gt;org.apache.commons.lang3.StringUtils&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0e84b5; font-weight: bold;&quot;&gt;org.hibernate.context.spi.CurrentTenantIdentifierResolver&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;

&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0e84b5; font-weight: bold;&quot;&gt;com.example.util.TenantContextHolder&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;

&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;/**&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * Hibernate needs to know which database to use i.e. which tenant to connect&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * to. This class provides a mechanism to provide the correct datasource at run&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * time.&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * @see {@link com.example.util.TenantContextHolder}&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * @see {@link com.example.security.CustomAuthenticationFilter}&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt; */&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #555555; font-weight: bold;&quot;&gt;@Component&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #bb0066; font-weight: bold;&quot;&gt;CurrentTenantIdentifierResolverImpl&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;implements&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; CurrentTenantIdentifierResolver &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;

    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; String DEFAULT_TENANT_ID &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;tenant_1&quot;&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;

    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;/*&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     * (non-Javadoc)&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     * @see org.hibernate.context.spi.CurrentTenantIdentifierResolver#&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     * resolveCurrentTenantIdentifier()&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     */&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0066bb; font-weight: bold;&quot;&gt;resolveCurrentTenantIdentifier&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;// The tenant is stored in a ThreadLocal before the end user&#39;s login information&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;// is submitted for spring security authentication mechanism. Refer to&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;// CustomAuthenticationFilter&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;background-color: yellow;&quot;&gt;String tenant &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; TenantContextHolder&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getTenant&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; StringUtils&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0000cc;&quot;&gt;isNotBlank&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;tenant&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; tenant &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; DEFAULT_TENANT_ID&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;

    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;/*&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     * (non-Javadoc)&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     * @see org.hibernate.context.spi.CurrentTenantIdentifierResolver#&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     * validateExistingCurrentSessions()&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #888888;&quot;&gt;     */&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333399; font-weight: bold;&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #0066bb; font-weight: bold;&quot;&gt;validateExistingCurrentSessions&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
        &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #008800; font-weight: bold;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;

&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #333333;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- End code highlighted by hilite.me --&gt;
 
&lt;br /&gt;
&lt;br /&gt;
Please note the yellow highlighted line in the code above which retrieves the tenant identifier. I will explain how it was stored and retrieved in the next file description.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
File: TenantContextHolder.java&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
When Spring Security parses the login form which has the extra &#39;tenant&#39; field, the field value is important. This value is the tenant identifier which will Hibernate which data source to use to connect to the desired tenant database.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html&quot; target=&quot;_blank&quot;&gt;ThreadLocal&lt;/a&gt; is a good solution to storing this tenant identifier. Please refer to the javadocs for a detailed explanation and some example code to understand the concept if you are new to it.&lt;br /&gt;
&lt;br /&gt;
The following diagram shows how the tenant id is retrieved from the login form and stored in a ThreadLocal variable and finally retrieved from this variable to identify the tenant database.&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVc6kzVK2YD1EehtcTxTIfQ92CHISw01S3ctHn5NfdJ2KYh2H_OkXtXrnaMBQtOMvk23wAshO9z30PXl6rSQjVndQ1g_UNOZTlA_2IrZL9Bpknu8VNrKs-wxAfWaw-Vsk-ep-_h95NB53Q/s1600/ThreadLocal.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img alt=&quot;ThreadLocal storage to store and retrieve tenant identifier&quot; border=&quot;0&quot; data-original-height=&quot;320&quot; data-original-width=&quot;414&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVc6kzVK2YD1EehtcTxTIfQ92CHISw01S3ctHn5NfdJ2KYh2H_OkXtXrnaMBQtOMvk23wAshO9z30PXl6rSQjVndQ1g_UNOZTlA_2IrZL9Bpknu8VNrKs-wxAfWaw-Vsk-ep-_h95NB53Q/s1600/ThreadLocal.png&quot; title=&quot;ThreadLocal storage to store and retrieve tenant identifier&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;ThreadLocal storage to store and retrieve tenant identifier&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
The example application uses the following code for a ThreadLocal variable&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;util&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;


&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * When the end user submits the login form, the tenant id is required to&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * determine which database to connect to. This needs to be captured in the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * spring security authentication mechanism, specifically in the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link UsernamePasswordAuthenticationFilter} implemented by&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link CustomAuthenticationFilter}. This tenant id is then required by the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link CurrentTenantIdentifierResolver} implemeted by the&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * {@link CurrentTenantIdentifierResolverImpl}&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &amp;lt;b&amp;gt;Explanation:&amp;lt;/b&amp;gt; Thread Local can be considered as a scope of access, like&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * a request scope or session scope. It’s a thread scope. You can set any object&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * in Thread Local and this object will be global and local to the specific&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * thread which is accessing this object. Global and local at the same time? :&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &amp;lt;ul&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &amp;lt;li&amp;gt;Values stored in Thread Local are global to the thread, meaning that they&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * can be accessed from anywhere inside that thread. If a thread calls methods&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * from several classes, then all the methods can see the Thread Local variable&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * set by other methods (because they are executing in same thread). The value&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * need not be passed explicitly. It’s like how you use global variables.&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &amp;lt;li&amp;gt;Values stored in Thread Local are local to the thread, meaning that each&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * thread will have it’s own Thread Local variable. One thread can not&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * access/modify other thread’s Thread Local variables.&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @see https://dzone.com/articles/painless-introduction-javas-threadlocal-storage&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;TenantContextHolder&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; ThreadLocal&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; CONTEXT &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; ThreadLocal&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setTenantId&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String tenant&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        CONTEXT&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;tenant&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getTenant&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; CONTEXT&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        CONTEXT&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;remove&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- End HTML generated by hilite.me --&gt;

&lt;/div&gt;
&lt;br /&gt;
These are the significant files for the application. The application described in this blog post is checked into GitHub where you can see other code not explained here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Modifying the Spring Boot main application class&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Typically, the Spring Boot main application class is nothing special as it has a main method which starts the application. But there is a lot of Spring Boot magic going on behind the scenes. A lot of defaults are assumed, a lot of configurations are done automatically by detecting artifacts in the classpath, application properties file and pom.xml analysis.&lt;br /&gt;
&lt;br /&gt;
If you are familiar with Spring Boot and JPA or even JDBC, then you know that any mention of spring jpa properties in the application properties file will cause Spring Boot to automatically configure the datasource. In this web application, we dont want Spring Boot to configure the data sources because we want to define multiple data sources and there is no default data source available when the application starts. Only when a user logs in with tenant information, the correct datasource needs to be used to connect to the tenant database.&lt;br /&gt;
&lt;br /&gt;
So, using a simple &lt;b&gt;exclude&lt;/b&gt; attribute to exclude the &lt;a href=&quot;https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.html&quot; target=&quot;_blank&quot;&gt;DataSourceAutoConfiguration&lt;/a&gt; class in the main &lt;span style=&quot;background-color: yellow;&quot;&gt;@SpringBootApplication&lt;/span&gt; annotation, we can tell Spring Boot to leave data source configuration aside.&lt;br /&gt;
&lt;br /&gt;
Since we have asked Spring Boot to not do some auto configuration related to data sources, it is a good idea to specifically ask Spring Boot to enable JPA Repositories using the &lt;a href=&quot;https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/config/EnableJpaRepositories.html&quot; target=&quot;_blank&quot;&gt;@EnableJpaRepositories&lt;/a&gt; annotation.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.SpringApplication&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.autoconfigure.SpringBootApplication&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.data.jpa.repository.config.EnableJpaRepositories&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author Sunit Katkar&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since 1.0 (April 2018)&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@SpringBootApplication&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;exclude &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt; DataSourceAutoConfiguration&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;})&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@EnableJpaRepositories&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;com.example.repository&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;MultitenancyMySqlApplication&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;[]&lt;/span&gt; args&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        SpringApplication&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;MultitenancyMySqlApplication&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; args&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- End code highlighted by hilite.me --&gt;

&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Sample SQL to create a tenant database on MySQL&amp;nbsp;&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Had this example been set up as a single database application and the property&amp;nbsp;&lt;span style=&quot;background-color: yellow;&quot;&gt;spring.jpa.hibernate.ddl-auto&lt;/span&gt; set to create or update, then the following three tables would be generated automatically by Hibernate based on the JPA entity definitions. Read more about it &lt;a href=&quot;https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Table: User&lt;/h3&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; (
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;user_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;INT&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;11&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;password&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;VARCHAR&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;255&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;username&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;VARCHAR&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;255&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;active&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;BIT&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;DEFAULT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;tenant&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;VARCHAR&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;255&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;DEFAULT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; (&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;user_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;)
)
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;COLLATE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;latin1_swedish_ci&#39;&lt;/span&gt;
ENGINE&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;MyISAM
;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- End hilite.me generated html --&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Table: Role&lt;/h3&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;role&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; (
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;role_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;INT&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;11&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;role&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;VARCHAR&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;255&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;DEFAULT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; (&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;role_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;)
)
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;COLLATE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;latin1_swedish_ci&#39;&lt;/span&gt;
ENGINE&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;MyISAM
;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;!-- End hilite.me generated html --&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Table: User_Role&lt;/h3&gt;
This is the mapping table where users and roles are recordeed&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;user_role&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; (
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;user_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;INT&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;11&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;role_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;INT&lt;/span&gt;(&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;11&lt;/span&gt;) &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; (&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;user_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;, &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;role_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;),
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;INDEX&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;FKa68196081fvovjhkek5m97n3y&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt; (&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;role_id&lt;span style=&quot;color: #333333;&quot;&gt;`&lt;/span&gt;)
)
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;COLLATE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;latin1_swedish_ci&#39;&lt;/span&gt;
ENGINE&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;MyISAM
;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- End hilite.me generated html --&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Resources&amp;nbsp;&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
The complete &lt;a href=&quot;https://github.com/sunitk/multitenancy&quot;&gt;source code&lt;/a&gt; is checked into GitHub. Its a standard Maven project which you can import into your IDE.&amp;nbsp;
&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/h3&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Conclusion
&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
I have explained multi-tenancy and shown you with example code how you can build a SaaS style &#39;tenant per database&#39; multi-tenant web application with Spring Boot; and how to secure it with Spring Security. I will write about adapting this code to use Microsoft SQL Server in a future blog post as there were some challenges and how I had to change some code to overcome them.&lt;br /&gt;
&lt;br /&gt;
Please do let me know your feedback by adding it in the comments section below. I am sure I will learn something new.&lt;br /&gt;
&lt;br /&gt;
Happy coding :)&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2018/04/building-saas-style-multi-tenant-web2.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVc6kzVK2YD1EehtcTxTIfQ92CHISw01S3ctHn5NfdJ2KYh2H_OkXtXrnaMBQtOMvk23wAshO9z30PXl6rSQjVndQ1g_UNOZTlA_2IrZL9Bpknu8VNrKs-wxAfWaw-Vsk-ep-_h95NB53Q/s72-c/ThreadLocal.png" height="72" width="72"/><thr:total>24</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-1884445007637259896</guid><pubDate>Wed, 24 Jan 2018 00:28:00 +0000</pubDate><atom:updated>2018-01-23T16:28:43.045-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">faster jackson</category><category domain="http://www.blogger.com/atom/ns#">javascript object notation</category><category domain="http://www.blogger.com/atom/ns#">JSON</category><category domain="http://www.blogger.com/atom/ns#">Spring</category><category domain="http://www.blogger.com/atom/ns#">Spring Boot</category><title>Small JSON utility methods for your Spring Boot app</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
JSON is almost the &lt;i&gt;lingua-franca&lt;/i&gt; when it comes to communication between web-services or Ajax based browser to server communication, though its not limited to just these two.&lt;/div&gt;
&lt;br /&gt;
There are many good JSON utilities and libraries like the the &lt;a href=&quot;https://github.com/FasterXML/jackson&quot; target=&quot;_blank&quot;&gt;faster jackson&lt;/a&gt; library. The maven repository page is &lt;a href=&quot;https://mvnrepository.com/artifact/com.fasterxml.jackson.core&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Purpose of this blog post&lt;/h3&gt;
&lt;br /&gt;
I am sharing two simple methods which I have used and continue to use a lot in all my projects requiring JSON. I understand that there maybe better versions and utilities out there, but I wanted to share what I learnt and developed and use in my work.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Using Faster Jackson in your Spring Boot app&lt;/h3&gt;
&lt;br /&gt;
Include the following dependency in your pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.fasterxml.jackson.core&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;jackson-databind&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
In your project&#39;s utility class, you can add the following methods - to convert to and from JSON.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Method 1 - To convert a JSON string to a Java POJO.&amp;nbsp;&lt;/h4&gt;
This is typically useful when the browser sends back form data to the server and you want to process it and convert it to a POJO.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * Converts a JSON string to a Java POJO&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * @param json&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; *            the JSON string&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * @param clazz&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; *            the class of the POJO that will be returned&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * @return instance of T&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span style=&quot;color: #666666;&quot;&gt;&amp;gt;&lt;/span&gt; T fromJson&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;String json&lt;span style=&quot;color: #666666;&quot;&gt;,&lt;/span&gt; Class&lt;span style=&quot;color: #666666;&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span style=&quot;color: #666666;&quot;&gt;&amp;gt;&lt;/span&gt; clazz&lt;span style=&quot;color: #666666;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;{&lt;/span&gt;
    ObjectMapper mapper &lt;span style=&quot;color: #666666;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;new&lt;/span&gt; ObjectMapper&lt;span style=&quot;color: #666666;&quot;&gt;();&lt;/span&gt;
    mapper&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;configure&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;DeserializationFeature&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;FAIL_ON_IGNORED_PROPERTIES&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;)&lt;/span&gt;
            &lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;configure&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;DeserializationFeature&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;FAIL_ON_UNKNOWN_PROPERTIES&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;)&lt;/span&gt;
            &lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;configure&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;DeserializationFeature&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;ACCEPT_SINGLE_VALUE_AS_ARRAY&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;T&lt;span style=&quot;color: #666666;&quot;&gt;)&lt;/span&gt; mapper&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;readValue&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;json&lt;span style=&quot;color: #666666;&quot;&gt;,&lt;/span&gt; clazz&lt;span style=&quot;color: #666666;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #666666;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;IOException e&lt;span style=&quot;color: #666666;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;{&lt;/span&gt;
        LOG&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;e&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;getMessage&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(),&lt;/span&gt; e&lt;span style=&quot;color: #666666;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #666666;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #666666;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Method 2 - To convert a POJO to a JSON string&lt;/h4&gt;
This is typically useful when the server sends data back to the browser. Notice that you can send back JSON as a simple String or with proper indentations and line feeds so that the string prints out a well formatted JSON.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * Convert a Java POJO to a JSON string&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * @param obj&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; *            the Java POJO&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * @param prettyPrint&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; *            if true then the string will be indented and the &lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; *            {@link ObjectMapper#writerWithDefaultPrettyPrinter()}&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; *            will be used to generate a well formatted human &lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; *            readable JSON string&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; * @return String in json format&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;static&lt;/span&gt; String &lt;span style=&quot;color: blue;&quot;&gt;toJson&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;Object obj&lt;span style=&quot;color: #666666;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #b00040;&quot;&gt;boolean&lt;/span&gt; prettyPrint&lt;span style=&quot;color: #666666;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;{&lt;/span&gt;
    ObjectMapper mapper &lt;span style=&quot;color: #666666;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;new&lt;/span&gt; ObjectMapper&lt;span style=&quot;color: #666666;&quot;&gt;();&lt;/span&gt;
    mapper&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;configure&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;SerializationFeature&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;FAIL_ON_EMPTY_BEANS&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;);&lt;/span&gt;
    String s &lt;span style=&quot;color: #666666;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;{&lt;/span&gt;
        s &lt;span style=&quot;color: #666666;&quot;&gt;=&lt;/span&gt; prettyPrint &lt;span style=&quot;color: #666666;&quot;&gt;?&lt;/span&gt; mapper&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;writerWithDefaultPrettyPrinter&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;writeValueAsString&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;obj&lt;span style=&quot;color: #666666;&quot;&gt;)&lt;/span&gt;
                &lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; mapper&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;writeValueAsString&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;obj&lt;span style=&quot;color: #666666;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #666666;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;JsonProcessingException e&lt;span style=&quot;color: #666666;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #666666;&quot;&gt;{&lt;/span&gt;
        LOG&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(&lt;/span&gt;e&lt;span style=&quot;color: #666666;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #7d9029;&quot;&gt;getMessage&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(),&lt;/span&gt; e&lt;span style=&quot;color: #666666;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #666666;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;return&lt;/span&gt; s&lt;span style=&quot;color: #666666;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #666666;&quot;&gt;}&lt;/span&gt;   
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Happy coding :)&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2018/01/small-json-utility-methods-for-your.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-2201164365523507571</guid><pubDate>Tue, 23 Jan 2018 19:40:00 +0000</pubDate><atom:updated>2018-01-23T11:40:43.184-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">CRUD operations</category><category domain="http://www.blogger.com/atom/ns#">JVM arguments</category><category domain="http://www.blogger.com/atom/ns#">setting timezone</category><category domain="http://www.blogger.com/atom/ns#">Spring</category><category domain="http://www.blogger.com/atom/ns#">Spring 4</category><category domain="http://www.blogger.com/atom/ns#">Spring 5</category><category domain="http://www.blogger.com/atom/ns#">Spring Boot</category><category domain="http://www.blogger.com/atom/ns#">Timezone</category><category domain="http://www.blogger.com/atom/ns#">UTC</category><title>Setting the timezone for your Spring Boot app</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Purpose of this blog post&lt;/h3&gt;
Today all non-trivial web applications and web services get deployed in the cloud. One cannot be very sure in which time zone the app is deployed. But sometimes, the app needs to record everything like log statements, database CRUD operations, etc using a specific time zone. Usually using the UTC time zone works best for such applications.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Setting the time zone&amp;nbsp;&lt;/h3&gt;
This short blog post is a way to show how this can be achieved in a java application, specifically a Spring or Spring Boot application.&lt;br /&gt;
&lt;br /&gt;
There are many ways to do it like passing arguments to the JVM at start time which sets the time zone.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;java &lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt;Duser&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;timezone&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;PST &lt;span style=&quot;color: #333333;&quot;&gt;...&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;app&lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt;main&lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt;class&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
But this is not the best solution as your app might not be the only application running on the JVM. There might be other apps running there too.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Setting time zone easily in Spring Boot

&lt;/h3&gt;
Add the following snippet to your Spring Boot application, typically in the main application class to set the desired time zone. The snippet shows the UTC time zone.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.TimeZone&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.annotation.PostConstruct&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.SpringApplication&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.boot.autoconfigure.SpringBootApplication&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;MyApplication&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;[]&lt;/span&gt; args&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        SpringApplication&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Ver3Application&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; args&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    
    &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@PostConstruct&lt;/span&gt;
    &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setUTCTimeZone&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(){&lt;/span&gt;
        TimeZone&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setDefault&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;TimeZone&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getTimeZone&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;UTC&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Happy coding :)
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2018/01/setting-timezone-for-your-spring-boot.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-4912303783031522020</guid><pubDate>Sat, 30 Dec 2017 01:51:00 +0000</pubDate><atom:updated>2017-12-29T17:53:11.118-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">DateTime</category><category domain="http://www.blogger.com/atom/ns#">Force.com API</category><category domain="http://www.blogger.com/atom/ns#">Meta data</category><category domain="http://www.blogger.com/atom/ns#">Salesforce Apex</category><category domain="http://www.blogger.com/atom/ns#">Salesforce API</category><category domain="http://www.blogger.com/atom/ns#">SOQL</category><category domain="http://www.blogger.com/atom/ns#">SOSL</category><category domain="http://www.blogger.com/atom/ns#">Time</category><title>Some utility methods when writing Salesforce APEX code</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Purpose of this blog post&lt;/h3&gt;
&lt;div&gt;
When you work with &lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dev_guide.htm&quot; target=&quot;_blank&quot;&gt;Salesforce APEX language&lt;/a&gt; you come across the &lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql.htm&quot; target=&quot;_blank&quot;&gt;Salesforce Object Query Language or SOQL&lt;/a&gt;. Any non-trivial APEX script will have some SOQL in it. SOQL is like the standard SQL but with some differences which are more suited to accessing and manipulating Salesforce objects and records.&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I found that I needed a few things always in APEX scripts and so extracted them into a utility class. This short blog post is about these code snippets which I have collected in my utility class.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Many of you are seasoned Salesforce professionals, but I thought of putting these simple utility methods on my blog for quick reference when I need them and for others who might shave off some time of their development work.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=523151633387570637#SOQLSelect&quot;&gt;Getting all fields of an object for a SOQL Select statement OR Select * for SOQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=523151633387570637#FieldType&quot;&gt;Getting the field type of a custom object&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=523151633387570637#Duration&quot;&gt;Finding the duration between two dates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;/h3&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/h3&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
A note about Salesforce APEX Exceptions&lt;/h3&gt;
&lt;div&gt;
In other programming languages like Java you can throw the provided exceptions like&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;IllegalArgumentException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(...);&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
But in APEX &lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_exception_custom.htm&quot; target=&quot;_blank&quot;&gt;you can catch but cannot throw provided exceptions&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So for my utility class, I created a simple exception using an existing APEX exception, like this&lt;/div&gt;
&lt;div&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;UtilityException&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;extends&lt;/span&gt; Exception&lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
I then use this exception for throwing my custom exception when I catch an APEX exception like DMLException, etc. Or I can throw this custom exception just like I would in a Java based method when some arguments are missing. Do&amp;nbsp;&lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_exception_custom.htm&quot; target=&quot;_blank&quot;&gt;read the link&lt;/a&gt;&amp;nbsp;to get a full understanding of APEX exceptions.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Tip:&lt;/b&gt; You can also include the above class definition within your Utility class and refer to it in the class. There is no strict requirement for it to be in a separate class file of its own. For readability and good code layout, I prefer to keep it in its own separate class file UtilityException.apxc&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 id=&quot;SOQLSelect&quot; style=&quot;text-align: left;&quot;&gt;
Getting all fields of an object for a SOQL Select statement OR Select * for SOQL&lt;/h3&gt;
&lt;div&gt;
The first thing you notice when working with SOQL to select is that there is no SQL equivalent of &#39;SELECT * FROM ...&#39;. With SQL, using &#39;Select * From&#39; is so common.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In SOQL you have to know the fields in an object to use them in your SELECT statement, but what if you just wanted to have all the fields in your statement like the SQL SELECT *. The following method uses the Salesforce API to get you just that.&lt;br /&gt;
&lt;br /&gt;
Tip: Do look up the documentation for &lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_schema.htm&quot; target=&quot;_blank&quot;&gt;Schema&lt;/a&gt; as that&#39;s what is in use here to get all the fields.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: solid gray; overflow: auto; padding: 0.2em 0.6em; text-align: left; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Provides a list of all fields in a Custom Object&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param sObjName - custom object name in string format e.g. &#39;Account&#39;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return - Returns List of all fields in a custom object&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getAllFieldsForSObject&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String sObjName&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;isBlank&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;sObjName&lt;span style=&quot;color: #333333;&quot;&gt;)){&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;UtilityException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;Argument &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;\&#39;&lt;/span&gt;sObjName&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;\&#39;&lt;/span&gt; missing&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;
                    &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;Custom Object Name is required&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; fieldList &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; 
                &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;(&lt;/span&gt;Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getGlobalDescribe&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt;
                                &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;sObjName&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
                                &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getDescribe&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt;
                                &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;fields&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getMap&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt;
                                &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;keySet&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; fieldList&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * Provides a SOQL equivalent of the SQL &#39;SELECT * FROM ..&#39; statement.&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     *&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @param sObjName - custom object name in string format e.g. &#39;Account&#39;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     * @return - Returns &#39;SELECT &amp;lt;field1&amp;gt;, &amp;lt;field2&amp;gt;,... FROM sObjName&#39;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;     */&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getAllFieldsInSOQLSelect&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String sObjName&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;isBlank&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;sObjName&lt;span style=&quot;color: #333333;&quot;&gt;)){&lt;/span&gt;
            &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;UtilityException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;Argument &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;\&#39;&lt;/span&gt;sObjName&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;\&#39;&lt;/span&gt; missing&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt; 
                    &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;Custom Object Name is required&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; fieldList &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; getAllFieldsForSObject&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;sObjName&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        String fields &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;fieldList&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #0044dd;&quot;&gt;&#39;,&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
        String soqlQuery &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;SELECT &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; fields &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt; FROM &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; sObjName&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; soqlQuery&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    
    &lt;span style=&quot;color: #888888;&quot;&gt;//Example usage:&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;//String selectSOQL = getAllFieldsInSOQLSelect(&#39;Account&#39;);&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&quot;FieldType&quot; style=&quot;text-align: left;&quot;&gt;
&lt;/h3&gt;
&lt;h3 id=&quot;FieldType&quot; style=&quot;text-align: left;&quot;&gt;
&lt;/h3&gt;
&lt;h3 id=&quot;FieldType&quot; style=&quot;text-align: left;&quot;&gt;
Getting the field type of a custom object&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Sometimes, you have to know the data type of a field in a custom object. Well, you can see your custom object with all its fields and relationships in the Salesforce org UI, but when writing APEX scripts or when using the Salesforce SOAP API, you want to know the field type.&lt;/div&gt;
&lt;br /&gt;
I needed to get a simple idea if a field was a String, a Number, a Date or a DateTime. So I wrote this simple method which does the job. You can always improvise on it, but do let me know so that I can post it here and also use it for my work :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- start code snippet --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Provides the type of a field on a custom object. &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param sObjName - custom object name in string format e.g. &#39;Opportunity&#39;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param fieldName - custom object field name in string format e.g. &#39;Area__c&#39;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @return - Returns &#39;STRING&#39; or &#39;DATE&#39; or &#39;DATETIME&#39; or &#39;NUMBER&#39;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt; 
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getFieldType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String sObjName&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String fieldName&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
    String fieldType &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;isBlank&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;sObjName&lt;span style=&quot;color: #333333;&quot;&gt;)){&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;UtilityException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;Argument &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;\&#39;&lt;/span&gt;sObjName&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;\&#39;&lt;/span&gt; missing&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt; 
                    &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;Custom Object Name is required&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;isBlank&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;fieldName&lt;span style=&quot;color: #333333;&quot;&gt;)){&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;UtilityException&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;Argument &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;\&#39;&lt;/span&gt;fieldName&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;\&#39;&lt;/span&gt; missing&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt; 
            &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;Custom Object Field Name is required&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    
    Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;SObjectType&lt;/span&gt; objType &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getGlobalDescribe&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;sObjName&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DescribeSObjectResult&lt;/span&gt; descObjResult &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; objType&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getDescribe&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DescribeFieldResult&lt;/span&gt; field &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; descObjResult&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;fields&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getMap&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt;
                                        &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;fieldName&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
                                        &lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getDescribe&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DATE&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
        fieldType &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;DATE&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DATETIME&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
        fieldType &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;DATETIME&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DOUBLE&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;||&lt;/span&gt; 
              field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;INTEGER&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
        fieldType &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;NUMBER&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;ADDRESS&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;||&lt;/span&gt; 
              field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;STRING&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;||&lt;/span&gt; 
              field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;PHONE&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;||&lt;/span&gt;
              field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;TEXTAREA&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;||&lt;/span&gt;
              field&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; Schema&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;DisplayType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;PICKLIST&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
                  fieldType &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;STRING&lt;span style=&quot;background-color: #ffaaaa; color: red;&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
              &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; fieldType&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- end code snippet --&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;h3 id=&quot;Duration&quot; style=&quot;text-align: left;&quot;&gt;
Finding the duration between two dates
&lt;/h3&gt;
&lt;/div&gt;
This is a standard requirement in many programming tasks to calculate the duration between two dates or the time elapsed between two dates. Other programming languages like Java have many utilities but here is something I wrote for APEX.&lt;br /&gt;
&lt;br /&gt;
There are two main data types in APEX to deal with date and time - &lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_time.htm&quot; target=&quot;_blank&quot;&gt;Time &lt;/a&gt;and &lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_datetime.htm#apex_methods_system_datetime&quot; target=&quot;_blank&quot;&gt;DateTime&lt;/a&gt;. I have used these to come up with these utility methods. Do read up on these and you might get some more utility methods out of it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- code snippet --&gt;
&lt;!-- HTML generated using hilite.me --&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Provides the Time between two times - startTime and endTime&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param startTime - the start time&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param endTime - the end time&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @return - the duration between two Time instances &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; Time &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GetTimeBetween&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Time startTime&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; Time endTime&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;startTime &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;||&lt;/span&gt; endTime &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
        &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; Time&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;newInstance&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    
    Integer elapsedHours &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; endTime&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt; startTime&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    Integer elapsedMinutes &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; endTime&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt; startTime&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    Integer elapsedSeconds &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; endTime&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;second&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt; startTime&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;second&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    Integer elapsedMiliseconds &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; endTime&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;millisecond&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt; startTime&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;millisecond&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
    
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; Time&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;newInstance&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;elapsedHours&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; elapsedMinutes&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; 
                    elapsedSeconds&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; elapsedMiliseconds&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Provides the Time between two DateTimes - startTime and endTime&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param startDate - the start date&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @param endDate - the end date&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @return - the duration between two DateTime instances&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; Time &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GetTimeBetweenDates&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;DateTime startDate&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; DateTime endDate&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;startDate &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;||&lt;/span&gt; endDate &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;){&lt;/span&gt;
     &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; Time&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;newInstance&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GetTimeBetween&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;startDate&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;time&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(),&lt;/span&gt; endDate&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;time&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;//Example Usage:&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;//DateTime startDate = DateTime.newInstance(2017, 12, 29, 20, 30, 00);&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;//DateTime endDate = DateTime.newInstance(2017, 12, 29, 21, 45, 00);&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;//Time duration = GetTimeBetweenDates(startDate, endDate);&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;//System.debug(&#39;Duration:&#39; + duration); &amp;lt;-- Duration:01:15:00.000Z&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;!-- /code snippet --&gt;

&lt;br /&gt;
&lt;br /&gt;
Do let me know if you have some of your own&amp;nbsp; APEX tips and tricks to share.&lt;br /&gt;
&lt;br /&gt;
Happy APEX coding :)&amp;nbsp;&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2017/12/some-utility-methods-when-writing.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-3994873181840938331</guid><pubDate>Tue, 21 Nov 2017 00:26:00 +0000</pubDate><atom:updated>2017-11-20T16:28:40.269-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Authentication</category><category domain="http://www.blogger.com/atom/ns#">REST</category><category domain="http://www.blogger.com/atom/ns#">RestController OAuth2</category><category domain="http://www.blogger.com/atom/ns#">Salesforce</category><category domain="http://www.blogger.com/atom/ns#">Salesforce Apex</category><category domain="http://www.blogger.com/atom/ns#">Salesforce REST</category><category domain="http://www.blogger.com/atom/ns#">Spring Boot</category><category domain="http://www.blogger.com/atom/ns#">Spring RestTemplate</category><title>Spring Boot RestTemplate to call Salesforce REST API</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Purpose of this blog post&lt;/h2&gt;
Using Spring Boot &lt;a href=&quot;https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-restclient.html&quot; target=&quot;_blank&quot;&gt;RestTemplate&lt;/a&gt; to communicate with a REST API is nothing new. There are many examples on the net. Using RestTemplate to communicate with a Salesforce REST API is also not&amp;nbsp; new and there are many examples out there. This post is an attempt to share my learnings with many others who are not new to Spring Boot RestTemplate but maybe relatively new to the Salesforce REST API. &lt;u&gt;Its my attempt to share the things I discovered and provide a quick way to accomplish this REST based communication&lt;/u&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Example Scenario&lt;/h2&gt;
You have written a REST API in your Salesforce instance to get details of Accounts. You now want to use an external host like a Heroku hosted java application to query this API and get the results.&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Prerequisites&lt;/h2&gt;
&lt;div&gt;
I am assuming you are quite comfortable with Java and Spring Boot. I further assume that you are familiar with Salesforce and can find your way by reading the online documentation and help topics published by Salesforce.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Java&lt;/h3&gt;
&lt;div&gt;
You know what you need, but I will list what I used&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Spring STS IDE&lt;/li&gt;
&lt;li&gt;Java 8&lt;/li&gt;
&lt;li&gt;Spring Boot 1.5.6.RELEASE&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
I am assuming you are familiar with creating a Spring Boot starter project either in your STS IDE or from the &lt;a href=&quot;https://start.spring.io/&quot; target=&quot;_blank&quot;&gt;Spring Initializr site&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;/h4&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Salesforce&amp;nbsp;&lt;/h3&gt;
I am assuming you have access to a Salesforce instance. If not, &lt;a href=&quot;https://developer.salesforce.com/signup&quot; target=&quot;_blank&quot;&gt;signup&lt;/a&gt; for a free developer edition. I further assume that you know how to create a connected app and write a simple Apex class with SOQL queries to query for standard or custom objects. This blog post cannot cover all the basics of Salesforce and the Apex programming language.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Steps to take on Salesforce side&lt;/h2&gt;
&lt;div&gt;
You need to do two things on the salesforce side -&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Create a new connected application or use an existing connected application.&lt;/li&gt;
&lt;li&gt;Create a Apex class and expose it via the Salesforce REST API mechanism&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Create a new connected application&lt;/h3&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Create a connected app and ensure that you enable OAuth. Details &lt;a href=&quot;https://help.salesforce.com/articleView?id=connected_app_create.htm&amp;amp;type=0&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Use an existing connected application&amp;nbsp;&lt;/h3&gt;
&lt;div&gt;
If you already have a connected app and have not enabled OAuth, then follow these steps&lt;/div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Click on the connected app name.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsJx78KcBqlh2kflogGleT2HJabUlRnW29rLp8lByqhlO44RV8WOHmYaKNe3KXhgZFYZTBuN4-7PzQsz9Y89myiFz3PGWl9bkyjnKJcWPH2b2AYXN5PbKdoHQ-dYdna5JgYd_yibAEv2kH/s1600/blog-02-01.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Connected Apps&quot; border=&quot;0&quot; data-original-height=&quot;302&quot; data-original-width=&quot;527&quot; height=&quot;183&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsJx78KcBqlh2kflogGleT2HJabUlRnW29rLp8lByqhlO44RV8WOHmYaKNe3KXhgZFYZTBuN4-7PzQsz9Y89myiFz3PGWl9bkyjnKJcWPH2b2AYXN5PbKdoHQ-dYdna5JgYd_yibAEv2kH/s320/blog-02-01.png&quot; title=&quot;Connected Apps&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;On the page showing your app details, look at the OAuth Policies section. For getting this example to work, ensure that the &lt;b&gt;IP Relaxation&lt;/b&gt; has a value of &lt;b&gt;&quot;Relax IP restrictions&quot;&lt;/b&gt;. &lt;br /&gt;What this means is that any host can connect with your app. Later on, you can fine tune access based on a set of IP addresses. (Initially, I was unable to connect to the REST API and received error messages when I called the API using CURL from the command line. Finally, I figured out that I needed to set this feature to relax the IP addresses which can call the Salesforce API.)&lt;/li&gt;
&lt;li&gt;Now go the &lt;b&gt;Setup&lt;/b&gt; page by clicking the link on the top right in the header of the page (next to your name. For the new Lightning Experience UI, this is in a drop down menu.).&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Using the left search menu look for &quot;Apps&quot;&lt;/li&gt;
&lt;li&gt;Click on the &lt;b&gt;Apps&lt;/b&gt; option under the &lt;b&gt;Build&lt;/b&gt; -&amp;gt; &lt;b&gt;Create&lt;/b&gt; menu on the left side.&lt;/li&gt;
&lt;li&gt;You should see your existing connected app listed in the Connected Apps section at the bottom of the page on the right side.&lt;/li&gt;
&lt;li&gt;Once again, click on the name of your app to see the details page of your app&lt;/li&gt;
&lt;li&gt;Click on the&amp;nbsp;&lt;b&gt;Edit&lt;/b&gt;&amp;nbsp;button to edit your application settings&lt;/li&gt;
&lt;li&gt;On the edit page, enable OAuth and enter data to make your app&#39;s OAuth settings look similar to this screen shot.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYeQ54nwaNKS5lO3Juoaj5-fZYDfksXiJ8OI-G-mWA0V5aQszN36GoqL9g6laD_ft7ODFi2QIwx-T8qWDYyih_wEvluiiaEORNAzMM0Fm6fc3L04umRxaEKvdXbY2LPDAfvM0bfCfn2ddO/s1600/blog-02-02.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;OAuth settings&quot; border=&quot;0&quot; data-original-height=&quot;605&quot; data-original-width=&quot;1199&quot; height=&quot;161&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYeQ54nwaNKS5lO3Juoaj5-fZYDfksXiJ8OI-G-mWA0V5aQszN36GoqL9g6laD_ft7ODFi2QIwx-T8qWDYyih_wEvluiiaEORNAzMM0Fm6fc3L04umRxaEKvdXbY2LPDAfvM0bfCfn2ddO/s320/blog-02-02.PNG&quot; title=&quot;OAuth settings&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;When you enable OAuth and click &lt;b&gt;Save&lt;/b&gt; you should see the &lt;b&gt;API (Enable OAuth Settings) &lt;/b&gt;section populated with important data which is required for connecting to your Salesforce REST API from an external REST client.&lt;/li&gt;
&lt;li&gt;Copy the &lt;b&gt;Consumer Key&lt;/b&gt; and store it safely. This will be the &lt;b&gt;client_id&lt;/b&gt; will be used in the API client code for authentication&lt;/li&gt;
&lt;li&gt;Click on the &lt;b&gt;Click to reveal&lt;/b&gt; link next to the &lt;b&gt;Consumer Secret&lt;/b&gt; to view the value and store it safely. This will be the &lt;b&gt;client_secret&lt;/b&gt; which will be used in the API client code for authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Writing a Apex class and exposing it via REST&lt;/h3&gt;
Its quite easy to write an Apex class and expose it via REST. The following example code returns just 2 Account objects when invoked via the REST url. You should refer the &lt;a href=&quot;https://developer.salesforce.com/page/Creating_REST_APIs_using_Apex_REST&quot; target=&quot;_blank&quot;&gt;official Salesforce documentation&lt;/a&gt; for details.&lt;br /&gt;
&lt;br /&gt;
Create a new Apex class, named anything you like, as follows using the Dev console.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: &amp;quot;arial&amp;quot;; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; @RestResource(urlMapping = &#39;/Account/*&#39;)  
 global with sharing class MyRestResource {  
   @HttpGet  
   global static List&amp;lt;Account&amp;gt; getAccounts() {  
     List&amp;lt;Account&amp;gt; result = [SELECT Id, Name, Phone, Website FROM Account LIMIT 2];  
     return result;  
   }  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Now work is done from Salesforce side. If you are familiar with Curl then you can try calling this URL and test the response. Note that you will have to authenticate first to obtain a OAuth token to access the REST url.&lt;br /&gt;
&lt;br /&gt;
Setting up the Spring Boot RestTemplate code&lt;br /&gt;
&lt;br /&gt;
The following code is brief and meant to just shows how to authenticate and then access the REST url.&amp;nbsp; I assume that you are familiar with creating a Spring Boot starter app.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Configure the Spring RestTemplate&lt;/h4&gt;
Create a package called config , e.g. com.example.config in your project and copy paste the following class. This will set some defaults like timeout for attributes of the RestTemplate. For more details refer the Spring docs at this&amp;nbsp;&lt;a href=&quot;https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.html&quot; target=&quot;_blank&quot;&gt;link&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.http.client.ClientHttpRequestFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.http.client.HttpComponentsClientHttpRequestFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Component&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;RestTemplateConfig&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
 
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Bean&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; ClientHttpRequestFactory &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;clientHttpRequestFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;int&lt;/span&gt; timeout &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;5000&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
  HttpComponentsClientHttpRequestFactory clientHttpRequestFactory &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; HttpComponentsClientHttpRequestFactory&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  clientHttpRequestFactory&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setConnectTimeout&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;timeout&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  clientHttpRequestFactory&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setConnectionRequestTimeout&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;timeout&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  clientHttpRequestFactory&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setReadTimeout&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;timeout&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; clientHttpRequestFactory&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;/h4&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Code that authenticates and calls the REST api&lt;/h4&gt;
The following code will first authenticate with the Salesforce OAuth service and then call the REST url.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Map&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.slf4j.Logger&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.http.HttpEntity&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.http.HttpHeaders&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.http.HttpMethod&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.http.HttpStatus&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.http.MediaType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.http.ResponseEntity&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.util.LinkedMultiValueMap&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.util.MultiValueMap&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.web.bind.annotation.GetMapping&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.web.bind.annotation.RestController&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.web.client.RestTemplate&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.salesforce.bigobjects.config.RestTemplateConfig&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@RestController&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;RestTemplateRequestToSalesforce&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;final&lt;/span&gt; Logger LOG &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; LoggerFactory&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getLogger&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;RestTemplateRequestToSalesforce&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;// Inject the Rest template configuration&lt;/span&gt;
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Autowired&lt;/span&gt;
 RestTemplateConfig restConfig&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * Simple Rest end point in this app to demonstrate authenticating and then calling the Salesforce REST url&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  * @return&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt;  */&lt;/span&gt;
 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@GetMapping&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/accounts&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;callRestUrl&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// First define the OAuth2 token URL as follows by replacing YOUR_INSTANCE&lt;/span&gt;
  &lt;span style=&quot;color: #888888;&quot;&gt;// with the actual instance that you have your org on&lt;/span&gt;
  String oauthUrl &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://YOUR_INSTANCE.salesforce.com/services/oauth2/token&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// Create a multi value map to put necessary attributes&lt;/span&gt;
  &lt;span style=&quot;color: #888888;&quot;&gt;// for the authentication request&lt;/span&gt;
  MultiValueMap&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; mvMap &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; LinkedMultiValueMap&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
  mvMap&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;grant_type&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  mvMap&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;client_id&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Your Client Id&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  mvMap&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;client_secret&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Your Client Secret&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  mvMap&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Your username&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  mvMap&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Your password&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// Create an instance of the RestTemplate&lt;/span&gt;
  RestTemplate restTemplate &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; RestTemplate&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;restConfig&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;clientHttpRequestFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// Send the REST request to get authenticated and receive an OAuth token&lt;/span&gt;
  Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; token &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;)&lt;/span&gt; restTemplate&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;postForObject&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;oauthUrl&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; mvMap&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; Map&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;--------------------------------------------&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Access Token  :: &quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; token&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;access_token&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
  LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Instance Url  :: &quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; token&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;instance_url&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
  LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Id  :: &quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; token&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
  LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Token_Type  :: &quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; token&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;token_type&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
  LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Signature  :: &quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; token&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;signature&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;));&lt;/span&gt;
  LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;--------------------------------------------&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// The oauth token is now required for all further calls to the REST resources&lt;/span&gt;
  String oauthToken &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; token&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;access_token&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// The REST url of your Salesforce Apex class will be of the form&lt;/span&gt;
  String restUrl &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://YOUR_ISTANCE.salesforce.com/services/apexrest/Account&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// Create Http headers and add the oauth token to them&lt;/span&gt;
  HttpHeaders restHeaders &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; HttpHeaders&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  restHeaders&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;setContentType&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;MediaType&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;APPLICATION_JSON&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  restHeaders&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;X-PrettyPrint&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  restHeaders&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;OAuth &quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; oauthToken&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// Create a Multi value map in case there are query params. In this example&lt;/span&gt;
  &lt;span style=&quot;color: #888888;&quot;&gt;// there are none so just an empty map is okay&lt;/span&gt;
  MultiValueMap&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; mv2Map &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; LinkedMultiValueMap&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// Following example code is using the RestTemplate exchange(..) method for making a GET request&lt;/span&gt;
  &lt;span style=&quot;color: #888888;&quot;&gt;// Other methods like getForEntity() or getForObject() can also be used.&lt;/span&gt;
  HttpEntity&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; restRequest &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; HttpEntity&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&amp;gt;(&lt;/span&gt;mv2Map&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; restHeaders&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  RestTemplate getRestTemplate &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; RestTemplate&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;restConfig&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;clientHttpRequestFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;());&lt;/span&gt;
  &lt;span style=&quot;color: #888888;&quot;&gt;// Make a request and read the response string&lt;/span&gt;
  ResponseEntity&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; responseStr &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; getRestTemplate&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;exchange&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;restUrl&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; HttpMethod&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;GET&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; restRequest&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
    String&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

  &lt;span style=&quot;color: #888888;&quot;&gt;// Return just the body of the response. You can examine the headers, etc if you wish&lt;/span&gt;
  HttpStatus responseStatus &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; responseStr&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getStatusCode&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  HttpHeaders responseHeaders &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; responseStr&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getHeaders&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  String responseBody &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; responseStr&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getBody&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  LOG&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;REST API response:&quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; responseBody&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; responseBody&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Summary&lt;/h3&gt;
The code is quite straightforward. Authenticate and obtain an OAuth token. Use this token is subsequent requests.&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2017/11/spring-boot-resttemplate-to-call.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsJx78KcBqlh2kflogGleT2HJabUlRnW29rLp8lByqhlO44RV8WOHmYaKNe3KXhgZFYZTBuN4-7PzQsz9Y89myiFz3PGWl9bkyjnKJcWPH2b2AYXN5PbKdoHQ-dYdna5JgYd_yibAEv2kH/s72-c/blog-02-01.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-3345171268244825399</guid><pubDate>Mon, 23 Oct 2017 21:53:00 +0000</pubDate><atom:updated>2017-10-23T14:54:17.010-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">domain model</category><category domain="http://www.blogger.com/atom/ns#">HTML forms</category><category domain="http://www.blogger.com/atom/ns#">POJO</category><category domain="http://www.blogger.com/atom/ns#">Spring</category><category domain="http://www.blogger.com/atom/ns#">spring mvc</category><title>Sending form data as a custom object to a Spring MVC Controller</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Form Data and Spring MVC Controllers&lt;/h3&gt;
In a Spring MVC application, sending form data to the controller is quite well known and trivial. Typically all data gets sent as a bunch of key=value pairs. Each key is a request param which can be captured in the Controller using the&amp;nbsp;&lt;span style=&quot;background-color: yellow; font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@RequestParam(&quot;key&quot;) String key&lt;/span&gt; construct in the method signature.&lt;br /&gt;
&lt;br /&gt;
If the number of fields are less, then you can use the request param construct to capture each form field, but if there are several form fields, then using this approach can create a unwieldy method signature and create room for error.&lt;br /&gt;
&lt;br /&gt;
There are several ways to collect form data but in this post, I am going to address one specific use case.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Motivation for this post&lt;/h3&gt;
Recently, someone at work asked me how to send data so that it was received by the Spring controller as a custom object/Pojo. I suggested using javascript to massage and format the data as desired and then send it.&lt;br /&gt;
&lt;br /&gt;
Now using &lt;a href=&quot;http://malsup.com/jquery/form/&quot; target=&quot;_blank&quot;&gt;jquery forms&lt;/a&gt; on the browser side you can send data in any format after converting it to a JSON string.&lt;br /&gt;
&lt;br /&gt;
For some business reasons, javascript was not an option. The HTML form had to be submitted as is using traditional http post method.&lt;br /&gt;
&lt;br /&gt;
The purpose of this short blog post is to demonstrate how to send data from the browser without the help of javascript or any jquery plugins. This is typically useful when you have checkboxes and radio buttons in the UI and there is a relation between them.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Example&lt;/h3&gt;
I have created an example UI which shows the kind of form that was to be submitted and then the controller code which processes the http post of this form.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEtGH9pGRIi6RqTIAxDpHowqncHGYSCjdwz55tSltPv63aS28VikzMlOD23keFlqx47HS-5GverHJprIqU0eBzQgt5Q1oRxAeukQhblY0QzVA7tPoICDH1xvfrhXmte_5rMgU5fRAakLd-/s1600/blog-01.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;263&quot; data-original-width=&quot;887&quot; height=&quot;118&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEtGH9pGRIi6RqTIAxDpHowqncHGYSCjdwz55tSltPv63aS28VikzMlOD23keFlqx47HS-5GverHJprIqU0eBzQgt5Q1oRxAeukQhblY0QzVA7tPoICDH1xvfrhXmte_5rMgU5fRAakLd-/s400/blog-01.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, this form shows a list of car makes and their colors. The idea is that the user will check a checkbox for a car make and then select a color using the radio buttons.&lt;br /&gt;
&lt;br /&gt;
Note that this form is rendered on the server side by reading the car makes and colors and then sent as a HTML page to the browser.&lt;br /&gt;
&lt;br /&gt;
The HTML generated for this form is like this&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style=&quot;background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: &amp;quot;arial&amp;quot;; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; &amp;lt;form name=&quot;customObjectForm&quot; id=&quot;customObjectForm&quot; method=&quot;post&quot; action=&quot;/submit&quot;&amp;gt;  
   &amp;lt;table class=&quot;table table-striped table-condensed table-bordered&quot;&amp;gt;  
     &amp;lt;thead&amp;gt;  
       &amp;lt;tr&amp;gt;  
         &amp;lt;th&amp;gt;Vehicle&amp;lt;/th&amp;gt;  
         &amp;lt;th&amp;gt;Select&amp;lt;/th&amp;gt;  
         &amp;lt;th&amp;gt;Color&amp;lt;/th&amp;gt;  
       &amp;lt;/tr&amp;gt;  
     &amp;lt;/thead&amp;gt;  
     &amp;lt;tbody&amp;gt;  
       &amp;lt;tr&amp;gt;  
         &amp;lt;td&amp;gt;Toyota Camry&amp;lt;/td&amp;gt;  
         &amp;lt;td&amp;gt;&amp;lt;input type=&quot;checkbox&quot; name=&quot;carModel&quot; value=&quot;Camry&quot; /&amp;gt;&amp;lt;/td&amp;gt;  
         &amp;lt;td&amp;gt;  
           &amp;lt;input type=&quot;radio&quot; name=&quot;colors[Camry]&quot; value=&quot;RED&quot; /&amp;gt; RED &amp;amp;nbsp;  
           &amp;lt;input type=&quot;radio&quot; name=&quot;colors[Camry]&quot; value=&quot;YELLOW&quot; /&amp;gt; YELLOW&amp;amp;nbsp;  
           &amp;lt;input type=&quot;radio&quot; name=&quot;colors[Camry]&quot; value=&quot;GREEN&quot; /&amp;gt; GREEN&amp;amp;nbsp;  
         &amp;lt;/td&amp;gt;  
       &amp;lt;/tr&amp;gt;  
       &amp;lt;tr&amp;gt;  
         &amp;lt;td&amp;gt;Honda Civic&amp;lt;/td&amp;gt;  
         &amp;lt;td&amp;gt;&amp;lt;input type=&quot;checkbox&quot; name=&quot;carModel&quot; value=&quot;Honda&quot; /&amp;gt;&amp;lt;/td&amp;gt;  
         &amp;lt;td&amp;gt;  
           &amp;lt;input type=&quot;radio&quot; name=&quot;colors[Honda]&quot; value=&quot;BLUE&quot; /&amp;gt; BLUE&amp;amp;nbsp;  
           &amp;lt;input type=&quot;radio&quot; name=&quot;colors[Honda]&quot; value=&quot;BLACK&quot; /&amp;gt; BLACK&amp;amp;nbsp;  
           &amp;lt;input type=&quot;radio&quot; name=&quot;colors[Honda]&quot; value=&quot;GREEN&quot; /&amp;gt; GREEN&amp;amp;nbsp;  
         &amp;lt;/td&amp;gt;  
       &amp;lt;/tr&amp;gt;  
     &amp;lt;/tbody&amp;gt;  
     &amp;lt;tfoot&amp;gt;  
       &amp;lt;tr&amp;gt;&amp;lt;td colspan=&quot;3&quot;&amp;gt;&amp;lt;input type=&quot;Submit&quot; name=&quot;submit&quot; class=&quot;btn btn-primary&quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;  
     &amp;lt;/tfoot&amp;gt;  
   &amp;lt;/table&amp;gt;  
 &amp;lt;/form&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Domain model



&lt;/h3&gt;
&lt;div&gt;
If you examine the HTML, you will notice that we can infer a Key Value pair type relationship between the car make and the color options. To relate the car make to the colors, the name of the radio buttons is named like an associative array with the car make as the value of the colors variable.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The car make checkboxes can be represented as a List in the domain model. If a user checks a checkbox then that checkbox value is submitted by the form, otherwise it is not.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Next, the row showing color options must be related to the car make in the domain model. To make that happen, the radio button selection can be submitted as a Map in the domain model.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So the car model can be a &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;List&amp;lt;String&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;carMakes&lt;/span&gt; and the car colors can be a &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Map&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;String, String&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;colors&lt;/span&gt; where the key is the car make and the value is the actual selected color.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
There can be a better domain model created and the HTML can be structured accordingly, but this is a quick example to show how Spring can convert browser submitted values in ready to use custom objects that you define.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here is the&amp;nbsp;&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CarMakeColorModel&lt;/span&gt;&lt;/b&gt; domain object / POJO.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;formobjects&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.List&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Map&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;CarMakeColorModel&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;// for the checkboxes for selecting the car makes&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; carMakes&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #888888;&quot;&gt;// for the radio buttons to select the car color&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; colors&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;CarMakeColorModel&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #888888;&quot;&gt;// default constructor&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;CarMakeColorModel&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; carMakes&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; colors&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;carMakes&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; carMakes&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;colors&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; colors&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;getCarMakes&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; carMakes&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setCarMakes&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; carMakes&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;carMakes&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; carMakes&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; getColors&lt;span style=&quot;color: #333333;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; colors&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;setColors&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; colors&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;colors&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; colors&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
On the Controller side, use the&amp;nbsp;&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring/docs/4.3.9.RELEASE/javadoc-api/org/springframework/web/bind/annotation/ModelAttribute.html&quot; target=&quot;_blank&quot;&gt;@ModelAttribute&lt;/a&gt;&lt;/span&gt;&lt;/b&gt; annotation to make Spring collect all the form submitted values and populate the CarMakeColorModel pojo.&lt;br /&gt;
&lt;br /&gt;
And here is the Spring Controller snippet which processes this HTML form.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;package&lt;/span&gt; com&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;example&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;formobjects&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;controllers&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.List&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;java.util.Map&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;javax.servlet.http.HttpServletRequest&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.stereotype.Controller&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.ui.ModelMap&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.web.bind.annotation.ModelAttribute&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.web.bind.annotation.RequestMapping&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;org.springframework.web.bind.annotation.RequestMethod&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;com.example.formobjects.model.CarMakeColorModel&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #888888;&quot;&gt;/**&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * Controller to handle the form submission&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * &lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @author &amp;lt;a href=&quot;mailto:sunitkatkar@gmail.com&quot;&amp;gt;Sunit Katkar&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @version 1.0&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; * @since Oct 2017&lt;/span&gt;
&lt;span style=&quot;color: #888888;&quot;&gt; */&lt;/span&gt;
&lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Controller&lt;/span&gt;
&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;FormCustomObjectController&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;value &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; method &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; RequestMethod&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;GET&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;ModelMap modelMap&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;index&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

 &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;value &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/submit&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; method &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; RequestMethod&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;POST&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;public&lt;/span&gt; String &lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;submit&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;HttpServletRequest request&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; ModelMap modelMap&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
   &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@ModelAttribute&lt;/span&gt; CarMakeColorModel carMakeColorModel&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;

  List&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; carMakes &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; carMakeColorModel&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getCarMakes&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  Map&lt;span style=&quot;color: #333333;&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; String&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gt;&lt;/span&gt; carColors &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; carMakeColorModel&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;getColors&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;();&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;String carModel &lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; carMakes&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
   String color &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; carColors&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;carModel&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
   System&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;out&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Car make:&quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; carModel &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot; Car color:&quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; color&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
  &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;index&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
What I have shown is a known way of processing forms completely on the server side without aid of javascript. Though many of you know this technique, I am sure there are some out there, like my colleague, who are not aware of this; hence this post.&lt;br /&gt;
&lt;br /&gt;
That&#39;s all there is to it. Happy coding :)&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2017/10/sending-form-data-as-custom-object-to.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEtGH9pGRIi6RqTIAxDpHowqncHGYSCjdwz55tSltPv63aS28VikzMlOD23keFlqx47HS-5GverHJprIqU0eBzQgt5Q1oRxAeukQhblY0QzVA7tPoICDH1xvfrhXmte_5rMgU5fRAakLd-/s72-c/blog-01.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-2483378721636795072</guid><pubDate>Tue, 26 Apr 2016 06:05:00 +0000</pubDate><atom:updated>2018-09-11T13:32:35.367-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">browser</category><category domain="http://www.blogger.com/atom/ns#">browser cache</category><category domain="http://www.blogger.com/atom/ns#">cache</category><category domain="http://www.blogger.com/atom/ns#">cache buster</category><category domain="http://www.blogger.com/atom/ns#">css</category><category domain="http://www.blogger.com/atom/ns#">existing MVC</category><category domain="http://www.blogger.com/atom/ns#">images</category><category domain="http://www.blogger.com/atom/ns#">javascript</category><category domain="http://www.blogger.com/atom/ns#">legacy apps</category><category domain="http://www.blogger.com/atom/ns#">proxy server</category><category domain="http://www.blogger.com/atom/ns#">resource handling</category><category domain="http://www.blogger.com/atom/ns#">resource versioning</category><category domain="http://www.blogger.com/atom/ns#">Spring 4</category><category domain="http://www.blogger.com/atom/ns#">spring mvc</category><category domain="http://www.blogger.com/atom/ns#">static resources</category><category domain="http://www.blogger.com/atom/ns#">xml config</category><title>Preventing caching of static resources in Spring MVC legacy projects using XML config </title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;script src=&quot;https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js&quot;&gt;&lt;/script&gt;
&lt;style&gt;
.prettyprint ol.linenums&gt;li {
  list-style-type: decimal;
  !
  important
}
&lt;/style&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;4&quot; cellspacing=&quot;4&quot; width=&quot;100%&quot; style=&quot;border: 1px solid black; border-collapse: collapse;&quot;&gt;
&lt;tr&gt;&lt;td&gt;&lt;h3&gt;Update (11 Sep 2018)&lt;/h3&gt;
&lt;p&gt;For Spring Boot 2, an updated version is available &lt;a href=&quot;https://sunitkatkar.blogspot.com/2018/09/spring-boot-2-thymeleaf-versioning.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;p&gt;&lt;p&gt;Do read this post first to understand how Spring handles resource url encoding and then proceed to the updated version.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;br/&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Resource caching&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Browsers typically cache static resources like javascript, css and image files. This is good as your app loads faster after the initial download of such resources. The next time around, if the resources have not changed, then the browser just fetches these from the cache.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Problems arise when you release the next version of your web application and the javascript, css or image files have changed. The browser will tend to get the files from it&#39;s own cache.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Well you know all of this, but I am just stating it here.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Preventing browser caching&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Typical web applications, built using different technologies like PHP, Python, Java Servlets, etc usually employ a simplistic approach of including a query parameter after the javascript file. This version is then changed for every release.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Example:&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&amp;lt;script href=&quot;/resources/scripts/myjscript.js?&lt;b&gt;v=1.1&lt;/b&gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
But this is mainly a manual process, though smart usage of build properties and build scripts can automate this to quite an extent. Spring does this versioning automatically for you and you need not make any special changes to your maven/gradle build scripts nor perform manual update of version numbers in any properties file.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Spring 4.1 offers an effective yet simple to setup way&amp;nbsp;&lt;/h3&gt;
Spring can create &lt;span style=&quot;background-color: yellow;&quot;&gt;fingerprints&lt;/span&gt; of your resource - javascript, css and image - urls. By fingerprints, it means that your url will have a MD5 hash in it. This hash is created by MD5 one-way hashing of the contents of your resource.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;/resources/scripts/&lt;b style=&quot;background-color: yellow;&quot;&gt;cachebuster2-36ed9000c1c01d0f17d42b18c814dcdb.js&lt;/b&gt;&lt;/pre&gt;
&lt;br /&gt;
All this is possible due to the &lt;a href=&quot;https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ResourceUrlEncodingFilter&lt;/span&gt;&lt;/a&gt;&amp;nbsp;and any one of the version resolvers like &lt;a href=&quot;https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/resource/VersionResourceResolver.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;VersionResourceResolver&lt;/span&gt;&lt;/a&gt; introduced in Spring 4.1. This official &lt;a href=&quot;https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources&quot; target=&quot;_blank&quot;&gt;Spring blog post&lt;/a&gt; will give you a clear idea. You should also read the &lt;a href=&quot;http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-config-static-resources&quot; target=&quot;_blank&quot;&gt;Spring documentation&lt;/a&gt;&amp;nbsp;on static content serving and the new facilities you get.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Why bother with XML config?&lt;/h3&gt;
Since Spring Boot has caught on rapidly, all new projects, examples and tutorials use the Java config way of configuring the application. But in an organisation there are legacy applications which were built using XML config. You do not have the luxury of updating the application by using Java Config.&lt;br /&gt;
&lt;br /&gt;
I have seen applications which use Spring 4.x and XML configuration though Java config has existed for some time before Spring 4. Sometimes, developers are used to the XML config and feel more comfortable using it. The reasons maybe many, but XML configs exist and will continue to for some time in the future.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note: &lt;/b&gt;&lt;br /&gt;
For those who want to do this using Java config, I have included a link to a very good tutorial on how to achieve this using Java config at the end of this blog post.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
What you need to do to bust that browser cache&lt;/h3&gt;
So, without further ado, this is what you need to do
&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Modify your web.xml to register a &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ResourceUrlEncodingFilter&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Configure any of the provided &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ResourceResolver&lt;/span&gt;s&lt;/li&gt;
&lt;li&gt;Use the Spring tag &lt;spring:url ...=&quot;&quot;&gt; or the JSTL &lt;c:url ...=&quot;&quot;&gt; tag to inject URLs of your static resources in your JSP page&lt;/c:url&gt;&lt;/spring:url&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Step 1: Modify the web.xml&lt;/h4&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-xml linenums&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;web-app version=&quot;2.5&quot; xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
 xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
 xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;&amp;gt;

 &amp;lt;!-- The definition of the Root Spring Container shared by all Servlets 
  and Filters --&amp;gt;
 &amp;lt;context-param&amp;gt;
  &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
  &amp;lt;param-value&amp;gt;/WEB-INF/spring/root-context.xml&amp;lt;/param-value&amp;gt;
 &amp;lt;/context-param&amp;gt;

 &amp;lt;!-- Creates the Spring Container shared by all Servlets and Filters --&amp;gt;
 &amp;lt;listener&amp;gt;
  &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;
 &amp;lt;/listener&amp;gt;
         &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt; &amp;lt;!-- Add the ResourceUrlEncodingFilter --&amp;gt;&lt;/pre&gt;
&amp;lt;filter&amp;gt;
  &amp;lt;filter-name&amp;gt;resourceUrlEncodingFilter&amp;lt;/filter-name&amp;gt;
  &amp;lt;filter-class&amp;gt;org.springframework.web.servlet.resource.ResourceUrlEncodingFilter&amp;lt;/filter-class&amp;gt;
 &amp;lt;/filter&amp;gt;
 &amp;lt;!-- Ensure that you map it to the DispatcherServlet --&amp;gt;
 &amp;lt;filter-mapping&amp;gt;
  &amp;lt;filter-name&amp;gt;resourceUrlEncodingFilter&amp;lt;/filter-name&amp;gt;
  &amp;lt;servlet-name&amp;gt;appServlet&amp;lt;/servlet-name&amp;gt;
 &amp;lt;/filter-mapping&amp;gt;
        
&amp;lt;!-- Processes application requests --&amp;gt;
 &amp;lt;servlet&amp;gt;
  &amp;lt;servlet-name&amp;gt;appServlet&amp;lt;/servlet-name&amp;gt;
  &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;
  &amp;lt;init-param&amp;gt;
   &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
   &amp;lt;param-value&amp;gt;/WEB-INF/spring/appServlet/servlet-context.xml&amp;lt;/param-value&amp;gt;
  &amp;lt;/init-param&amp;gt;
  &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
 &amp;lt;/servlet&amp;gt;

 &amp;lt;servlet-mapping&amp;gt;
  &amp;lt;servlet-name&amp;gt;appServlet&amp;lt;/servlet-name&amp;gt;
  &amp;lt;url-pattern&amp;gt;/&amp;lt;/url-pattern&amp;gt;
 &amp;lt;/servlet-mapping&amp;gt;
&amp;lt;/web-app&amp;gt;

&lt;/pre&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Step 2: Configure the ResourceResolver in the application context xml file&lt;/h4&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html linenums&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans:beans xmlns:mvc=&quot;http://www.springframework.org/schema/mvc&quot;
 xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
 xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
 xsi:schemaLocation=&quot;http://www.springframework.org/schema/mvc 
      http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context.xsd&quot;&amp;gt;

 &amp;lt;!-- DispatcherServlet Context: defines this servlet&#39;s request-processing 
  infrastructure --&amp;gt;

 &amp;lt;!-- Enables the Spring MVC @Controller programming model --&amp;gt;
 &amp;lt;mvc:annotation-driven /&amp;gt;
        &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt; &amp;lt;!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the 
                ${webappRoot}/resources directory. The resolvers help in adding either a version number or a 
                hash to the javascript, css, image urls to prevent browser caching --&amp;gt;&lt;/pre&gt;
&amp;lt;mvc:resources mapping=&quot;/resources/**&quot; location=&quot;/resources/&quot;&amp;gt;
  &amp;lt;mvc:resource-chain resource-cache=&quot;true&quot;
   auto-registration=&quot;true&quot;&amp;gt;
   &amp;lt;mvc:resolvers&amp;gt;
    &amp;lt;mvc:version-resolver&amp;gt;
     &amp;lt;mvc:content-version-strategy
      patterns=&quot;/**&quot; /&amp;gt;
     &amp;lt;!-- &amp;lt;mvc:fixed-version-strategy version=&quot;1.1.1&quot; patterns=&quot;/**&quot;/&amp;gt; --&amp;gt;
    &amp;lt;/mvc:version-resolver&amp;gt;
   &amp;lt;/mvc:resolvers&amp;gt;
  &amp;lt;/mvc:resource-chain&amp;gt;
 &amp;lt;/mvc:resources&amp;gt;
        
 &amp;lt;!-- Resolves views selected for rendering by @Controllers to .jsp resources 
  in the /WEB-INF/views directory --&amp;gt;
 &amp;lt;beans:bean
  class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&amp;gt;
  &amp;lt;beans:property name=&quot;prefix&quot; value=&quot;/WEB-INF/views/&quot; /&amp;gt;
  &amp;lt;beans:property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&amp;gt;
 &amp;lt;/beans:bean&amp;gt;

 &amp;lt;context:component-scan base-package=&quot;com.blogspot.sunitkatkar&quot; /&amp;gt;
&amp;lt;/beans:beans&amp;gt;
&lt;/pre&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
Step 3: Use the JSTL or Spring tags for URLs in your JSP pages
&lt;/h4&gt;
&lt;pre class=&quot;prettyprint lang-html linenums&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;pageEncoding=&quot;UTF-8&quot;%&amp;gt;
&amp;lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&amp;gt;
&amp;lt;%@ taglib prefix=&quot;spring&quot; uri=&quot;http://www.springframework.org/tags&quot;%&amp;gt;
&lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;&amp;lt;spring:url value=&quot;/resources/scripts/cachebuster2.js&quot; var=&quot;cachebusterjs&quot; /&amp;gt;
&amp;lt;c:url value=&quot;/resources/styles/cachebuster2.css&quot; var=&quot;cachebustercss&quot; /&amp;gt;
&lt;/pre&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Spring MVC Resource Versioning&amp;lt;/title&amp;gt;
&amp;lt;script src=&quot;https://code.jquery.com/jquery-2.2.3.min.js&quot;
 integrity=&quot;sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=&quot;
 crossorigin=&quot;anonymous&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;${cachebusterjs}&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link href=&quot;${cachebustercss}&quot; rel=&quot;stylesheet&quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;h1&amp;gt;Hello versioned static resources world!&amp;lt;/h1&amp;gt;
 &amp;lt;h4&amp;gt;The time on the server is ${serverTime}.&amp;lt;/h4&amp;gt;
 &amp;lt;p&amp;gt;JS url: ${cachebusterjs}&amp;lt;/p&amp;gt;
 &amp;lt;p&amp;gt;CSS url: ${cachebustercss}&amp;lt;/p&amp;gt;
 &amp;lt;p&amp;gt;
  &amp;lt;button id=&quot;btnWelcome&quot;&amp;gt;Click Me&amp;lt;/button&amp;gt;
 &amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Results&lt;/h3&gt;
&lt;div&gt;
If you run the project, you should see the main screen as below:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZbuBsrMXH2huxmautJ8IE_ljI-koLUb8XWHSEwFeXqkiHbd3LQZsos6Z1Ey-F2CBvjwmcxtnTGCSLl6JmVa_PZyg9ghIvyVltLQTiL6FEEKKQOqrzdSZayw1mkH57t5ufSdjNaUIMPAHh/s1600/screenshot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Fingerprint URLs&quot; border=&quot;0&quot; height=&quot;134&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZbuBsrMXH2huxmautJ8IE_ljI-koLUb8XWHSEwFeXqkiHbd3LQZsos6Z1Ey-F2CBvjwmcxtnTGCSLl6JmVa_PZyg9ghIvyVltLQTiL6FEEKKQOqrzdSZayw1mkH57t5ufSdjNaUIMPAHh/s320/screenshot.png&quot; title=&quot;Fingerprint URLs&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Resources&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;The above code has been uploaded as an example project &lt;/span&gt;&lt;a href=&quot;https://github.com/sunitk/examples/tree/master/cachebuster2&quot; style=&quot;font-family: inherit;&quot; target=&quot;_blank&quot;&gt;&quot;cachebuster2&quot;&lt;/a&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt; on github.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If you want to do this using Java config, this is a &lt;a href=&quot;http://www.mscharhag.com/spring/resource-versioning-with-spring-mvc&quot; target=&quot;_blank&quot;&gt;good example&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2016/04/preventing-caching-of-static-resources.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZbuBsrMXH2huxmautJ8IE_ljI-koLUb8XWHSEwFeXqkiHbd3LQZsos6Z1Ey-F2CBvjwmcxtnTGCSLl6JmVa_PZyg9ghIvyVltLQTiL6FEEKKQOqrzdSZayw1mkH57t5ufSdjNaUIMPAHh/s72-c/screenshot.png" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-3167207632826607442</guid><pubDate>Wed, 15 Jan 2014 12:52:00 +0000</pubDate><atom:updated>2014-02-23T15:22:20.432-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">add websockets</category><category domain="http://www.blogger.com/atom/ns#">existing MVC</category><category domain="http://www.blogger.com/atom/ns#">html5</category><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">jquery</category><category domain="http://www.blogger.com/atom/ns#">retrofit MVC</category><category domain="http://www.blogger.com/atom/ns#">sockjs</category><category domain="http://www.blogger.com/atom/ns#">Spring</category><category domain="http://www.blogger.com/atom/ns#">Spring 4</category><category domain="http://www.blogger.com/atom/ns#">Spring framework</category><category domain="http://www.blogger.com/atom/ns#">Spring security</category><category domain="http://www.blogger.com/atom/ns#">stomp</category><category domain="http://www.blogger.com/atom/ns#">twitter bootstrap</category><category domain="http://www.blogger.com/atom/ns#">websocket</category><category domain="http://www.blogger.com/atom/ns#">websockets in existing MVC</category><title>Spring 4 WebSockets with SockJS, STOMP and Spring Security 3.2</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;script defer=&quot;defer&quot; src=&quot;https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?autoload=true&amp;amp;skin=default&quot;&gt;&lt;/script&gt;
  &lt;style&gt;
.prettyprint ol.linenums&gt;li {
  list-style-type: decimal;
  !
  important
}
&lt;/style&gt;
  &lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;/div&gt;
&lt;h4 dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
    &lt;br /&gt;What are WebSockets?
  &lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
You may already know this, but I’m adding an &lt;a href=&quot;http://en.wikipedia.org/wiki/WebSocket&quot; target=&quot;_blank&quot;&gt;excerpt from Wikipedia&lt;/a&gt;.
  &lt;/div&gt;
&lt;blockquote dir=&quot;ltr&quot; style=&quot;border: solid 1px #CCC; text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;em&gt;WebSocket is a protocol providing &lt;/em&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Full-duplex&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;full-duplex&lt;/em&gt;&lt;/a&gt;&lt;em&gt; communications channels over a single TCP
      connection. The WebSocket protocol was standardized by the &lt;/em&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Internet_Engineering_Task_Force&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;IETF&lt;/em&gt;&lt;/a&gt;&lt;em&gt; as &lt;/em&gt;&lt;a href=&quot;http://tools.ietf.org/html/rfc6455&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;RFC 6455&lt;/em&gt;&lt;/a&gt;&lt;em&gt; in 2011.&lt;/em&gt;
  &lt;/blockquote&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Modern browsers like Google Chrome and FireFox have been supporting WebSockets for some time now.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4 dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
    Spring 4 and WebSockets&lt;br /&gt;
  &lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Spring has grown to be a full fledged Enterprise solution. The latest offering of interest in Spring 4 is the implementation of the WebSocket specification as per &lt;a href=&quot;https://www.jcp.org/en/jsr/detail?id=356&quot; target=&quot;_blank&quot;&gt;JSR 356&lt;/a&gt;. Oracle has already published a &lt;a href=&quot;http://docs.oracle.com/javaee/7/tutorial/doc/websocket.htm&quot; target=&quot;_blank&quot;&gt;tutorial&lt;/a&gt;
    on how to use the Java (Java EE 7.0) implementation of JSR 356. But I prefer to use the &lt;a href=&quot;http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#_websocket_sockjs_and_stomp_messaging&quot; target=&quot;_blank&quot;&gt;Spring 4 implementation&lt;/a&gt; so that it fits
    snugly in the Spring based ecosystem already in place. &lt;br /&gt;
&lt;br /&gt;
This diagram depicts what I have understood on how WebSockets work. Traditional HTTP is a Request and Response based system.
    WebSockets is a full duplex communication channel. Its like opening a socket connection from the browser to the web server. Usually you need a thick client like a Java applet or an ActiveX plugin
    to create and open a socket connection from the browser to the web server. With WebSockets this ‘socket connection’ is now provided by the browser and understood by the server. Please do not
    confuse WebSockets with TCP connections. Differences between these two are well explained in these stackoverflow answers &lt;a href=&quot;http://stackoverflow.com/questions/2681267/what-is-the-fundamental-difference-between-websockets-and-pure-tcp?lq=1&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://stackoverflow.com/questions/16945345/differences-between-tcp-sockets-and-web-sockets-one-more-time&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoGatOjPux7FVtdX8iNCRYM7hXY__sY1V1BFI9UI96Y5DmLyPGUcgjabuWUMXouerlclz7p6DIBcenqypajw2LkpKShuk1n6PX39ilRNkXkxu92nDrE0dESR22jebC01pbDzBU_pq5fPGP/s1600-h/learn-websockets-1-01%25255B6%25255D.png&quot;&gt;&lt;img alt=&quot;learn-websockets-1-01&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0Mq2ZYvuw1-EK31jSedwnmN8v4nQzxpQgSXzWl0OP3y56YO_QWIWraBs8u-TvCX97EDa_uip4DPj173R31wUa6taNEyJMlGdVLjHc72ZWcTWq0I09dxDPruSP4Gk6_n7a-vkPOE-d6Y2V/?imgmax=800&quot; height=&quot;201&quot; style=&quot;background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;learn-websockets-1-01&quot; width=&quot;528&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
Http uses the http:// and https:// for regular and secured connections respectively from the browser to the web server. With WebSockets you
    use the ws:// and wss:// for regular and secured connections respectively. &lt;br /&gt;
&lt;br /&gt;
Obviously you are not going to replace &lt;strong&gt;http://&lt;/strong&gt; with &lt;strong&gt;ws:// &lt;/strong&gt;in the
    browser’s address bar as you explore using WebSockets as an alternative to the prevalent Ajax communication. Read more on this topic &lt;a href=&quot;http://en.wikipedia.org/wiki/WebSocket&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Why should we bother about WebSockets? It’s just another transport mechanism …&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Do &lt;a href=&quot;http://www.youtube.com/watch?v=Z897fkPn7Rw&quot; target=&quot;_blank&quot;&gt;watch this video&lt;/a&gt; which shows a quick comparison on the performance of using WebSockets as a transport for real-time web
    applications, as opposed to the traditional HTTP (long) polling. &lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
YAWT (Yet Another WebSockets Tutorial) ??&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
There are many resources on this topic already on the web. Then why am I doing this? Well, I like to share what I learnt with others, in my own way.&lt;br /&gt;
&lt;br /&gt;
Also the &lt;a href=&quot;http://spring.io/guides/gs/messaging-stomp-websocket/&quot; target=&quot;_blank&quot;&gt;Spring example&lt;/a&gt; demonstrates WebSockets by using &lt;a href=&quot;http://projects.spring.io/spring-boot/&quot; target=&quot;_blank&quot;&gt;Spring
      Boot&lt;/a&gt;.
    &lt;br /&gt;
&lt;div style=&quot;border: 2px solid #990000;&quot;&gt;
I wanted to &#39;retro-fit&#39; my existing traditional Spring MVC application with WebSockets.&lt;/div&gt;
Hence this blog post. &lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Learning WebSockets&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I am sharing my WebSocket learning experience with you through the example below. We will build a simple web application which will connect with a WebSocket server and echo back messages that we
    send to it. Sounds boring, but it’s the most basic example on how to go about WebSockets. In a later post I will share something more meaty. &lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
What you will need&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Before we get into WebSockets, you will need the following:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://spring.io/tools/sts&quot; target=&quot;_blank&quot;&gt;Spring Tool Suite (STS)&lt;/a&gt; ver. 3.4.0 (You can use Eclipse or IntelliJ too. I prefer STS and this example was built using STS)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/downloads/index.html&quot; target=&quot;_blank&quot;&gt;Java 7&lt;/a&gt; (JDK 1.7_0_45)&lt;/li&gt;
&lt;li&gt;Tomcat&amp;nbsp; &lt;a href=&quot;http://tomcat.apache.org/download-70.cgi&quot; target=&quot;_blank&quot;&gt;ver. 7.0.47&lt;/a&gt;
      &lt;/li&gt;
&lt;li&gt;Spring &lt;a href=&quot;http://projects.spring.io/spring-framework/&quot; target=&quot;_blank&quot;&gt;4.0.0.RELEASE&lt;/a&gt; (See &lt;a href=&quot;http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/&quot; target=&quot;_blank&quot;&gt;Reference Documentation&lt;/a&gt;)
      &lt;/li&gt;
&lt;/ul&gt;
You don&#39;t need to create a fancy UI, but I decided to use some ready made UI components provided by Twitter Bootstrap. It creates &lt;a href=&quot;http://en.wikipedia.org/wiki/Responsive_web_design&quot; target=&quot;_blank&quot;&gt;responsive web pages&lt;/a&gt; which are suitable for rendering on mobile devices as well as traditional laptop screens. And all this without having to be a HTML5 and CSS expert! &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://getbootstrap.com/&quot; target=&quot;_blank&quot;&gt;Twitter Bootstrap ver 3.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
Spring 4 WebSockets natively supports SockJS on the server side. So you will need the client side SockJS javascript framework. For this you will need to download - &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jmesnil.net/stomp-websocket/doc/&quot; target=&quot;_blank&quot;&gt;Stomp Over Websocket&lt;/a&gt; (&lt;a href=&quot;https://raw.github.com/jmesnil/stomp-websocket/master/lib/stomp.js&quot; target=&quot;_blank&quot;&gt;download&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jquery.com/&quot; target=&quot;_blank&quot;&gt;JQuery&lt;/a&gt;&amp;nbsp; ver 1.10.2 (&lt;a href=&quot;http://code.jquery.com/jquery-1.10.2.min.js&quot; target=&quot;_blank&quot;&gt;download&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sockjs.org/&quot; target=&quot;_blank&quot;&gt;SockJS&lt;/a&gt; ver 0.3.4 (&lt;a href=&quot;https://github.com/sockjs/sockjs-client&quot; target=&quot;_blank&quot;&gt;download&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Do all browsers support WebSockets?&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Unfortunately, not all browsers support WebSockets. For example, IE10 was the first version of Internet Explorer browser to support it, while Google Chrome and FireFox have been supporting it
    since quite some time.&lt;br /&gt;
&lt;br /&gt;
Many organizations still use older versions of Internet Explorer. Not everyone uses Google Chrome or FireFox. So in such cases you need a way to fallback on
    some other mechanisms like Ajax to communicate with the server. Also some networks are configured in such a way &lt;a href=&quot;http://www.infoq.com/articles/Web-Sockets-Proxy-Servers&quot; target=&quot;_blank&quot;&gt;that
      proxies wont support WebSockets&lt;/a&gt;. In both cases you need a ‘fallback’ mechanism so that users can use WebSocket based applications. &lt;br /&gt;
You can test if your browser supports WebSockets by
    clicking &lt;a href=&quot;http://caniuse.com/websockets&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Project Setup&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Using STS, create a simple Spring MVC Web Application. See the following screenshots to setup your project.&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQrEWqrFj4Tg7JVgQXZcZmtFprvX9RXFqf6FJknfVf1ag0zV5RppGiqtsXwoPDWq56dvJBAGAgjR_1IO7bpLLMzm4QYmmI16K2YXKkRxU0REv3E8MjUKyjSBXRzdxUvq9qgvojrY_fRicK/s1600-h/project-setup-01%25255B25%25255D.png&quot;&gt;&lt;img alt=&quot;STS Project Setup 1: Select a wizard&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQYhDmO3gpgETU9hdjfKBym-Mw16__aK0mLMxijOTKWvk6FWGcdsjeu5OatNDD0dSb2PSBYsQGycN9Pqb4_lpYoYnfmtYbkp_t33RwHiMGTFhXpiIGAbFOgU7Oc9hYnBhCEeCLnCm2k-jp/?imgmax=800&quot; height=&quot;588&quot; style=&quot;background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;STS Project Setup 1: Select a wizard&quot; width=&quot;554&quot; /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;h2&gt;
STS Project Setup 1: Select a wizard&lt;/h2&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio7iSvjZMXsZynVlmIVxL6neH1S-7w0Da_bRmsL1D7-YdL6UH1tIuwlRWbEF3qjobu-ZsG0SMT5WFdiIpEHWtBlMP0bEQPRU7QhaMFWdu8LLi8331oCjWOcYZH5jgPEMf13Y8a1ifGudBD/s1600-h/project-setup-02%25255B4%25255D.png&quot;&gt;&lt;img alt=&quot;STS Project Setup 2: Select Template&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb0vT9WcLFVzWIUR3oHCpr844Jm88pITVZQL0cfkVYyQoSvmTg6je5jIMMFWR_uIL31UMwCoyj_H20owqvVCCokMYkQnq03tzwfjCZA01Y8gJoJJ-3DunjGzEerpRat-IXweQJjeft3xrL/?imgmax=800&quot; height=&quot;732&quot; style=&quot;background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;STS Project Setup 2: Select Template&quot; width=&quot;609&quot; /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;h2&gt;
STS Project Setup 2: Select Template&lt;/h2&gt;
&lt;strong&gt;Note:&lt;/strong&gt; We will change the Spring version 3.2.2 that the example MVC project uses to 4.0.0.RELEASE via the pom.xml file once the project is set up. &lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1-AD4wg_p1wbTiozkFaww4rLKmdULGvVRw94AcEp7lppduifpGM5xrYHs4MoCDQAr4SSfAdbTQpvmi98lTBlnBAfzn08z4fgzy7eQLwYIB3Cq6UB1DWZap50N4wDaDZj9V2UH7JfIl8_O/s1600-h/project-setup-03%25255B6%25255D.png&quot;&gt;&lt;img alt=&quot;STS Project Setup 3: Project Specific Settings&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLvgz2Q_OiWP3dvNZjYGydbuv2ZijkbgzpZ5xcStalCORilhpggCEMPYvLSYn0-zsshKORGgSyXav8iCKRdEy86x9TgL7-v7KJPobApQc-7uuUYrhKd2b0LTnKZ1JsYwcCt0cIoUcEN0u2/?imgmax=800&quot; height=&quot;456&quot; style=&quot;background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;STS Project Setup 3: Project Specific Settings&quot; width=&quot;521&quot; /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
STS Project Setup 3: Project Specific Settings&lt;/h2&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPGSdN0vnKsPJdpDs5_TH01UVt8osFFFrMERxUc9ryn8sgQvNil-2cmezkjDQvDOJQV89uUW5Pgb2iJK5CeTEPaS9RTmQqNb5rC_DGh86v6Fw6KV3TEkAnw1dNFVV-ggXteJJ9v_qiUDQZ/s1600-h/project-setup-04%25255B4%25255D.png&quot;&gt;&lt;img alt=&quot;STS Project Setup 4: Package Explorer&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7JnfNcF5MBUVSvOjRiXgM9gCmllCLmXvIA_pxbw2hzXXOICHp56bfNGeEG5DXETvz4DOizzCXa1i_RVTEEl8LAQzvwA3QQBMEfGu6IV7ERaLX9tzQmGgYloJ3QV37uqe0Lo2Oz2LfI_n8/?imgmax=800&quot; height=&quot;572&quot; style=&quot;background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;STS Project Setup 4: Package Explorer&quot; width=&quot;364&quot; /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;h2&gt;
STS Project Setup 4: Package Explorer&lt;/h2&gt;
After you have setup your project, you should have a project layout similar to the above screenshot. The packages like &lt;span style=&quot;font-family: courier new;&quot;&gt;com.blogspot.sunitkatkar.config&lt;/span&gt;
    , etc. will be added by you as you write code. The downloadable project file has the entire source code as per the screenshot below. &lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Modifying the pom.xml&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
We need to modify the example &lt;b&gt;pom.xml&lt;/b&gt; file to have the proper Spring version in place. Let&#39;s look at the first section of the pom.xml file.&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-xml&quot;&gt;&amp;lt;!-- Properties --&amp;gt;
&amp;lt;properties&amp;gt;
  &amp;lt;!-- pom.xml --&amp;gt;
  &amp;lt;!-- Generic properties --&amp;gt;
  &amp;lt;java-version&amp;gt;1.7&amp;lt;/java-version&amp;gt;
  &amp;lt;project.build.sourceEncoding&amp;gt;UTF-8&amp;lt;/project.build.sourceEncoding&amp;gt;
  &amp;lt;project.reporting.outputEncoding&amp;gt;UTF-8&amp;lt;/project.reporting.outputEncoding&amp;gt;

  &amp;lt;!-- Spring framework --&amp;gt;
  &amp;lt;org.springframework-version&amp;gt;4.0.0.RELEASE&amp;lt;/org.springframework-version&amp;gt;
  &amp;lt;org.springframework.security-version&amp;gt;3.2.0.RELEASE&amp;lt;/org.springframework.security-version&amp;gt;

  &amp;lt;!-- Logging - Using Logback instead of Log4J --&amp;gt;
  &amp;lt;logback.version&amp;gt;1.0.13&amp;lt;/logback.version&amp;gt;
  &amp;lt;org.slf4j-version&amp;gt;1.7.5&amp;lt;/org.slf4j-version&amp;gt;

  &amp;lt;!-- Web --&amp;gt;
  &amp;lt;jsp.version&amp;gt;2.2&amp;lt;/jsp.version&amp;gt;
  &amp;lt;jstl.version&amp;gt;1.2&amp;lt;/jstl.version&amp;gt;
  &amp;lt;servlet.version&amp;gt;3.1.0&amp;lt;/servlet.version&amp;gt;

  &amp;lt;!-- Test --&amp;gt;
  &amp;lt;junit.version&amp;gt;4.11&amp;lt;/junit.version&amp;gt;

&amp;lt;/properties&amp;gt;
&amp;lt;!-- /Properties --&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
The rest of the pom.xml is a standard pom for Spring MVC projects. I have been using Log4J for logging, but for this project I decided to try the newer logging framework &lt;a href=&quot;http://logback.qos.ch/&quot; target=&quot;_blank&quot;&gt;Logback&lt;/a&gt; by the creator of Log4J. More details &lt;a href=&quot;http://gordondickens.com/wordpress/2013/03/27/sawing-through-the-java-loggers/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Spring XML configuration&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
We are using XML based Spring configuration for this example. Here is the standard configuration via &lt;b&gt;servlet-context.xml&lt;/b&gt; file. &lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-xml&quot;&gt;    &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!-- servlet-context.xml --&amp;gt;
&amp;lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/mvc&quot;
  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; 
  xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
  xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
  xsi:schemaLocation=&quot;http://www.springframework.org/schema/mvc 
                      http://www.springframework.org/schema/mvc/spring-mvc.xsd
                      http://www.springframework.org/schema/beans 
                      http://www.springframework.org/schema/beans/spring-beans.xsd
                      http://www.springframework.org/schema/context 
                      http://www.springframework.org/schema/context/spring-context.xsd&quot;&amp;gt;

  &amp;lt;!-- DispatcherServlet Context: defines this servlet&#39;s request-processing infrastructure --&amp;gt;
  &amp;lt;context:component-scan base-package=&quot;com.blogspot.sunitkatkar&quot; /&amp;gt;

  &amp;lt;!-- Enables the Spring MVC @Controller programming model --&amp;gt;
  &amp;lt;annotation-driven /&amp;gt;

  &amp;lt;!-- Handles HTTP GET requests for /resources/** by efficiently serving 
    up static resources in the ${webappRoot}/resources directory --&amp;gt;
  &amp;lt;resources mapping=&quot;/resources/**&quot; location=&quot;/resources/&quot; /&amp;gt;

  &amp;lt;!-- Resolves views selected for rendering by @Controllers to .jsp resources 
    in the /WEB-INF/views directory --&amp;gt;
  &amp;lt;beans:bean class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&amp;gt;
    &amp;lt;beans:property name=&quot;prefix&quot; value=&quot;/WEB-INF/views/&quot; /&amp;gt;
    &amp;lt;beans:property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&amp;gt;
  &amp;lt;/beans:bean&amp;gt;
&amp;lt;/beans:beans&amp;gt;
    &lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Setting up Spring Security&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Today the trend is to use &lt;a href=&quot;http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-java&quot; target=&quot;_blank&quot;&gt;Java based application and application
      security configuration for Spring based apps&lt;/a&gt;. However, I want to retro-fit my existing Spring MVC secured web application. So I continue to use XML based security configuration. &lt;br /&gt;
&lt;br /&gt;
In our example, we want a simple login form. To achieve this, I have used the following security configuration via the application-security.xml file.&lt;br /&gt;
&lt;br /&gt;
By using Spring Security XML
    configuration element &amp;lt;form-login&amp;gt; we can restrict access to secured web pages. Any attempt to access these pages will result in a login form being shown to the user. Once the user enters
    credentials and is authenticated then access is granted to the secured pages.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-xml&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;
  xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans  
                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
                      http://www.springframework.org/schema/security 
                      http://www.springframework.org/schema/security/spring-security.xsd&quot;&amp;gt;


  &amp;lt;!-- Get a basic Spring Security provided form based login infra --&amp;gt;
  &amp;lt;http auto-config=&quot;true&quot; use-expressions=&quot;true&quot;&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/index&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/index.jsp&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/app/**&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/simplemessages/**&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/topic/**&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/topic/simplemessages&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/resources/**&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/login&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/loginPage&quot; access=&quot;permitAll&quot; /&amp;gt;
    &amp;lt;!-- Requests to secured pages need to be authenticated and authorized --&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/secured/*&quot;
      access=&quot;hasAnyRole(&#39;ROLE_ADMIN&#39;,&#39;ROLE_USER&#39;)&quot; /&amp;gt;
    &amp;lt;!-- Define the security form login and logout pages/urls --&amp;gt;
                &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;    &amp;lt;form-login login-processing-url=&quot;/login&quot; login-page=&quot;/loginPage&quot;
      username-parameter=&quot;username&quot; password-parameter=&quot;password&quot;
      default-target-url=&quot;/secured/basicWebsockets&quot;
      authentication-failure-url=&quot;/loginPage?auth=fail&quot; /&amp;gt;&lt;/pre&gt;
&amp;lt;logout invalidate-session=&quot;true&quot; logout-url=&quot;/logout&quot;
      logout-success-url=&quot;/logoutPage&quot; /&amp;gt;
  &amp;lt;/http&amp;gt;

  &amp;lt;!-- Define some example users and admins who have role based access to 
    the application. In a real world scenario this would be linked with a user 
    credentials database or a custom authentication provider. Some examples: 
    1) http://krams915.blogspot.in/2012/01/spring-security-31-implement_1244.html 
    2) http://krams915.blogspot.in/2010/12/spring-security-mvc-integration-using_26.html --&amp;gt;
  &amp;lt;authentication-manager&amp;gt;
    &amp;lt;authentication-provider&amp;gt;
      &amp;lt;user-service&amp;gt;
        &amp;lt;user name=&quot;john&quot; password=&quot;doe&quot; authorities=&quot;ROLE_USER&quot; /&amp;gt;
        &amp;lt;user name=&quot;sunit&quot; password=&quot;katkar&quot; authorities=&quot;ROLE_USER&quot; /&amp;gt;
        &amp;lt;user name=&quot;admin&quot; password=&quot;admin&quot; authorities=&quot;ROLE_USER,ROLE_ADMIN&quot; /&amp;gt;
      &amp;lt;/user-service&amp;gt;
    &amp;lt;/authentication-provider&amp;gt;
  &amp;lt;/authentication-manager&amp;gt;
&amp;lt;/beans:beans&amp;gt;
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;login-page:&lt;/b&gt; Mapping URL of the custom login page. If not defined, then Spring Security will create a default URL at &lt;i&gt;&lt;b&gt;&#39;/spring_security_login&#39;&lt;/b&gt;&lt;/i&gt; and render a default
        login form.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;login-processing-url:&lt;/b&gt; Login form needs to be posted to this URL. If not defined then, it needs to be posted to default URL &lt;i&gt;&lt;b&gt;&#39;/j_spring_security_check&#39;&lt;/b&gt;&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;username-parameter:&lt;/b&gt; Request parameter name which contains the username Default is &lt;i&gt;&lt;b&gt;&#39;j_username&#39;&lt;/b&gt;&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;password-parameter:&lt;/b&gt; Request parameter name which contains the password. Default is &lt;i&gt;&lt;b&gt;&#39;j_password&#39;&lt;/b&gt;&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;default-target-url:&lt;/b&gt; User will be redirected to this URL after successful login.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;authentication-failure-url:&lt;/b&gt; If authentication failed, then user will be forwarded to this URL. Default is &lt;i&gt;&lt;b&gt;&#39;/spring_security_login?login_error&#39;&lt;/b&gt;&lt;/i&gt;. In this example we
        have set it to &lt;i&gt;&lt;b&gt;&#39;/loginPage?auth=fail&#39;&lt;/b&gt;&lt;/i&gt;. That means user will be redirected to the same login page and there we&#39;ll use request parameter &#39;auth=fail&#39; as indicator to show the
        authentication failure message.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Adding Spring Security To The Spring MVC Web App&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Now that the Spring security configuration is done via the &lt;b&gt;application-security.xml&lt;/b&gt; file, it is time to combine it with Spring configuration file &lt;b&gt;servlet-context.xml&lt;/b&gt;. This is done
    via the &lt;b&gt;web.xml&lt;/b&gt;b&amp;gt; file as shown&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-xml&quot;&gt;    &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!-- web.xml --&amp;gt;
&amp;lt;web-app xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot;
  version=&quot;3.0&quot;&amp;gt;

  &amp;lt;!-- The definition of the Root Spring Container shared by all Servlets 
    and Filters --&amp;gt;
  &amp;lt;context-param&amp;gt;
    &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;
         /WEB-INF/spring/appServlet/servlet-context.xml
        &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt; /WEB-INF/application-security.xml&lt;/pre&gt;
&amp;lt;/param-value&amp;gt;
  &amp;lt;/context-param&amp;gt;

  &amp;lt;!-- Creates the Spring Container shared by all Servlets and Filters --&amp;gt;
  &amp;lt;listener&amp;gt;
    &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;
  &amp;lt;/listener&amp;gt;

  &amp;lt;!-- Processes application requests --&amp;gt;
  &amp;lt;servlet&amp;gt;
    &amp;lt;servlet-name&amp;gt;appServlet&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;init-param&amp;gt;
      &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
      &amp;lt;param-value&amp;gt;
          /WEB-INF/spring/appServlet/servlet-context.xml
      &amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
    &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
  &amp;lt;/servlet&amp;gt;

  &amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;appServlet&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/&amp;lt;/url-pattern&amp;gt;
  &amp;lt;/servlet-mapping&amp;gt;

  &amp;lt;!-- Spring standard form based login security --&amp;gt;
  &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;  &amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;springSecurityFilterChain&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;org.springframework.web.filter.DelegatingFilterProxy&amp;lt;/filter-class&amp;gt;
  &amp;lt;/filter&amp;gt;
  &lt;/pre&gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;springSecurityFilterChain&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
  &amp;lt;/filter-mapping&amp;gt;
&amp;lt;/web-app&amp;gt;
    &lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Spring MVC Controller&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In this example, there is a &lt;b&gt;LearnWebSocketsMVCController&lt;/b&gt; which receives all requests. We need to add methods to handle the requests for authentication as shown below.
    &lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-java&quot;&gt;/**
 * Copyright &amp;amp;copy; Sunit Katkar (sunitkatkar@gmail.com) http://sunitkatkar.blogspot.com
 */
package com.blogspot.sunitkatkar.controllers;

import java.security.Principal;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.blogspot.sunitkatkar.util.Util;

/**
 * {@link LearnWebSocketsMVCController} is for handling the user login and logout. Simple form based security is used.
 * Refer to &amp;lt;code&amp;gt;application-security.xml&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;web.xml&amp;lt;/code&amp;gt; for details.
 * 
 * @author &amp;lt;a href=&quot;mailto:sunitkatkar@gmail.com&quot;&amp;gt;Sunit Katkar&amp;lt;/a&amp;gt;
 * @since 1.0
 * @version 1.0.0.1
 */
@Controller
public class LearnWebSocketsMVCController {

    private static final Logger LOG = LoggerFactory.getLogger(LearnWebSocketsMVCController.class);

    /**
     * To handle the regular request to the application context. e.g. http://localhost:8080/learn-websockets-1
     * 
     * @param model
     * @param locale
     * @return
     */
    @RequestMapping(&quot;/&quot;)
    public String handleIndexPage(Model model, Locale locale) {
        LOG.info(&quot;Request for default / url processed at {}&quot;, Util.getSimpleDate());
        return &quot;loginPage&quot;;
    }

    /**
     * Method is executed when there is a call to the &amp;lt;code&amp;gt;/logoutPage&amp;lt;/code&amp;gt; url.
     * 
     * @return
     */
    &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;@RequestMapping(value = &quot;/logoutPage&quot;, method = RequestMethod.GET)&lt;/pre&gt;
public String logoutPage() {
        LOG.info(&quot;Request for /logoutPage url processed at {}&quot;, Util.getSimpleDate());
        return &quot;logoutPage&quot;;
    }

    /**
     * Method is executed when there is a call to the &amp;lt;code&amp;gt;/loginPage&amp;lt;/code&amp;gt; url. 
     * On successful login, the user is re-directed to the &amp;lt;code&amp;gt;/secured/myPage&amp;lt;/code&amp;gt; url.
     * 
     * @return
     */
    &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;@RequestMapping(value = &quot;/loginPage&quot;, method = RequestMethod.GET)&lt;/pre&gt;
public String loginPage() {
        LOG.info(&quot;Request for /loginPage url processed at {}&quot;, Util.getSimpleDate());
        return &quot;loginPage&quot;;
    }

    /**
     * Method gets executed when there are requests to the &amp;lt;code&amp;gt;/secured/basicWebsockets&amp;lt;/code&amp;gt; url. 
     * This url is called after a successful login.
     * 
     * @param model
     * @param principal
     * @param locale
     * @return
     */
    &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;@RequestMapping(&quot;/secured/basicWebsockets&quot;)&lt;/pre&gt;
public String basicWebsocketsPage(Model model, Principal principal, Locale locale) {

        // Get a simple human readable date and time
        String formattedDate = Util.getSimpleDate(locale);

        // Get the logged in user&#39;s name
        String userName = principal.getName();

        // Set some sample messages to show on the landing &#39;basicWebsockets.jsp&#39; page.
        model.addAttribute(&quot;username&quot;, userName);
        model.addAttribute(&quot;time&quot;, formattedDate);

        LOG.info(&quot;Request from user:{} for /secured/basicWebsockets url processed at time:{}&quot;, userName, formattedDate);

        return &quot;secured/basicWebsockets&quot;;
    }
}
   &lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
Creating Views Using JSP&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I have used Twitter Bootstrap to get a quick yet responsive and visually elegant user interface. This example has four jsp files.
    &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;index.jsp&lt;/b&gt; - Has a simple redirect to the loginPage.jsp&lt;/li&gt;
&lt;li&gt;&lt;b&gt;loginPage.jsp&lt;/b&gt; - To show the login form&lt;/li&gt;
&lt;li&gt;&lt;b&gt;logoutPage.jsp&lt;/b&gt; - To show the &#39;session ended&#39; message&lt;/li&gt;
&lt;li&gt;&lt;b&gt;basicWebsockets.jsp&lt;/b&gt; - The landing page after authentication. This also has the WebSockets user interface and client side code&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
index.jsp&lt;/h3&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-xml&quot;&gt;&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;
&amp;lt;c:redirect url=&quot;/loginPage&quot;/&amp;gt;
    &lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
loginPage.jsp&lt;/h3&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-xml&quot;&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&amp;gt;
&amp;lt;%@ taglib uri=&#39;http://java.sun.com/jsp/jstl/core&#39; prefix=&#39;c&#39;%&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot;&amp;gt;
&amp;lt;!--  Bootstrap related --&amp;gt;
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
&amp;lt;!-- Latest compiled and minified CSS --&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;&amp;lt;c:url value=&quot;/resources/scripts/bootstrap/css/bootstrap.min.css&quot;/&amp;gt;&quot;&amp;gt;
&amp;lt;%-- &amp;lt;link href=&quot;&amp;lt;c:url value=&quot;/resources/css/login.css&quot;/&amp;gt;&quot; rel=&quot;stylesheet&quot;&amp;gt; --%&amp;gt;
&amp;lt;title&amp;gt;Login :: Learn WebSockets&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;div class=&quot;container&quot;&amp;gt;
    &amp;lt;div class=&quot;span12&quot;&amp;gt;
      &amp;lt;div id=&quot;heading&quot; class=&quot;masthead&quot;&amp;gt;
        &amp;lt;h3 class=&quot;muted&quot;&amp;gt;Login&amp;lt;/h3&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&quot;row&quot;&amp;gt;
        &amp;lt;div class=&quot;col-sm-6&quot;&amp;gt;
          &amp;lt;div class=&quot;panel panel-default&quot;&amp;gt;
            &amp;lt;div class=&quot;panel-body&quot;&amp;gt;
              &amp;lt;form action=&quot;${pageContext.request.contextPath}/login&quot; method=&quot;post&quot; 
                  class=&quot;form-signin&quot; role=&quot;form&quot;&amp;gt;
                &amp;lt;div class=&quot;form-group&quot;&amp;gt;
                  &amp;lt;label for=&quot;username&quot;&amp;gt;User name:&amp;lt;/label&amp;gt; 
                  &amp;lt;input type=&quot;text&quot; name=&quot;username&quot; id=&quot;username&quot; class=&quot;form-control&quot; 
                    placeholder=&quot;User name&quot; required autofocus /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class=&quot;form-group&quot;&amp;gt;
                  &amp;lt;label for=&quot;password&quot;&amp;gt;Password:&amp;lt;/label&amp;gt; &amp;lt;input type=&quot;password&quot; name=&quot;password&quot; id=&quot;password&quot;
                    class=&quot;form-control&quot; placeholder=&quot;Password&quot; required&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;input name=&quot;submit&quot; type=&quot;submit&quot; value=&quot;Submit&quot; class=&quot;btn btn-success&quot;&amp;gt;
              &amp;lt;/form&amp;gt;
              &amp;lt;c:if test=&quot;${&#39;fail&#39; eq param.auth}&quot;&amp;gt;
                &amp;lt;p&amp;gt;
                &amp;lt;div class=&quot;alert alert-danger&quot;&amp;gt;Login Failed!!! Reason :
                  ${sessionScope[&quot;SPRING_SECURITY_LAST_EXCEPTION&quot;].message}&amp;lt;/div&amp;gt;
              &amp;lt;/c:if&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;!-- .panel-body --&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;!-- .panel --&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;!-- .span12 --&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;!-- .container --&amp;gt;
  &amp;lt;!-- .container --&amp;gt;
  &amp;lt;!-- Compiled and minified JQuery JavaScript (necessary for Bootstrap&#39;s JavaScript plugins). 
       Placed at the end of the document so the pages load faster --&amp;gt;
  &amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/jquery-1.10.2.min.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;!-- Include all compiled plugins (below), or include individual files as needed --&amp;gt;
  &amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/bootstrap/js/bootstrap.min.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
  &lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
logoutPage.jsp&lt;/h3&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-xml&quot;&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&amp;gt;
&amp;lt;%@ taglib uri=&#39;http://java.sun.com/jsp/jstl/core&#39; prefix=&#39;c&#39;%&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;!-- &amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&amp;gt; --&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot;&amp;gt;
&amp;lt;!--  Bootstrap related --&amp;gt;
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
&amp;lt;!-- Latest compiled and minified CSS --&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;&amp;lt;c:url value=&quot;/resources/scripts/bootstrap/css/bootstrap.min.css&quot;/&amp;gt;&quot;&amp;gt;
&amp;lt;title&amp;gt;Logout :: Learn WebSockets&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;div class=&quot;container&quot;&amp;gt;
    &amp;lt;div class=&quot;span12&quot;&amp;gt;
      &amp;lt;div id=&quot;heading&quot; class=&quot;masthead&quot;&amp;gt;
        &amp;lt;h3 class=&quot;muted&quot;&amp;gt;Logged Out&amp;lt;/h3&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&quot;row&quot;&amp;gt;
        &amp;lt;div class=&quot;col-sm-12&quot;&amp;gt;
          &amp;lt;div class=&quot;panel panel-default&quot;&amp;gt;
            &amp;lt;div class=&quot;panel-body&quot;&amp;gt;
              Your session has ended. Click here 
              to &amp;lt;a href=&quot;${pageContext.request.contextPath}/secured/basicWebsockets&quot;&amp;gt;login&amp;lt;/a&amp;gt;
              again.
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;!-- Compiled and minified JQuery JavaScript (necessary for Bootstrap&#39;s JavaScript plugins). 
    Placed at the end of the document so the pages load faster --&amp;gt;
  &amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/jquery-1.10.2.min.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;!-- Include all compiled plugins (below), or include individual files as needed --&amp;gt;
  &amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/bootstrap/js/bootstrap.min.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
   &lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
basicWebsockets.jsp&lt;/h3&gt;
We will look at this page after we delve into server and client side code for WebSockets&lt;/div&gt;
&lt;h4&gt;
Server side code for WebSockets&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Before we look at the client side javascript required for WebSockets, let&#39;s look at the server side code. We need to make our &#39;legacy&#39; MVC application aware of the new &#39;WebSockets&#39; feature.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Configuring WebSockets&lt;/h3&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
We have used XML for configuring the MVC app. Now this is the &#39;legacy&#39; app which we will retro-fit with WebSockets. Note that you can use &lt;a href=&quot;http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/websocket.html#websocket-stomp-handle&quot; target=&quot;_blank&quot;&gt;XML based WebSocket configuration&lt;/a&gt;, but we will use Java
    based configuration. You can mix and match XML and Java based configuration in a Spring MVC app. When starting new projects you can keep it clean by going either complete XML or complete Java
    based configuration. &lt;br /&gt;
&lt;br /&gt;
Here is Java based configuration for &#39;retro-fitting&#39; WebSockets in our MVC example via the &lt;b&gt;WebSocketConfig&lt;/b&gt; class. The source code has self explanatory
    comments.&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-java&quot;&gt;    
/**
 * Copyright &amp;amp;copy; 2013-2014 &amp;lt;a href=&quot;http://sunitkatkar.blogspot.com&quot;&amp;gt;Sunit&#39;s blog&amp;lt;/a&amp;gt;
 */
package com.blogspot.sunitkatkar.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

/**
 * Defines methods for configuring message handling with simple messaging
 * protocols (e.g. STOMP) from WebSocket clients. Typically used to customize
 * the configuration provided via the {@link EnableWebSocketMessageBroker}
 * annotation. &amp;lt;br/&amp;gt;
 * &amp;lt;br/&amp;gt;
 * WebSocketConfig is annotated with &amp;lt;code&amp;gt;@Configuration&amp;lt;/code&amp;gt; to indicate
 * that it is a Spring configuration class. It is also annotated with
 &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;* &amp;lt;code&amp;gt;@EnableWebSocketMessageBroker&amp;lt;/code&amp;gt;. As its name suggests,
 * &amp;lt;code&amp;gt;@EnableWebSocketMessageBroker&amp;lt;/code&amp;gt; enables WebSocket message
 * handling, backed by a message broker. &amp;lt;br/&amp;gt;&lt;/pre&gt;
* &amp;lt;br/&amp;gt;
 * Furthermore, this is also annotated with the &amp;lt;code&amp;gt;@EnableScheduling&amp;lt;/code&amp;gt;
 * annotation. This enables Spring&#39;s scheduled task execution ability.
 * 
 * @author &amp;lt;a href=&quot;mailto:sunitkatkar@gmail.com&quot;&amp;gt;Sunit Katkar&amp;lt;/a&amp;gt;
 * @since 1.0
 * @version 1.0.0.1
 */

@Configuration
&lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;@EnableWebSocketMessageBroker&lt;/pre&gt;
@EnableScheduling
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    /**
     * Configure STOMP over WebSocket end-points.
     * 
     * @see com.blogspot.sunitkatkar.WebSocketBroadcastController.controllers.WebsocketBroadcastController
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // The registerStompEndpoints() method registers the &quot;/simplemessages&quot;
        // endpoint, enabling SockJS fallback options so that alternative
        // messaging options may be used if WebSocket is not available. This
        // endpoint when prefixed with &quot;/app&quot;, is the endpoint that the
        // WebSocketBroadcastController.processMessageFromClient() method is
        // mapped to handle.
        registry.addEndpoint(&quot;/simplemessages&quot;).withSockJS();
    }

    /**
     * Configure message broker options.
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        // The configureMessageBroker() method overrides the default method in
        // WebSocketMessageBrokerConfigurer to configure the message broker. It
        // starts by calling enableSimpleBroker() to enable a simple
        // memory-based message broker to carry the greeting messages back to
        // the client on destinations prefixed with &quot;/topic/&quot;. It also
        // designates the &quot;/app&quot; prefix for messages that are bound for
        // @MessageMapping-annotated methods.

        config.enableSimpleBroker(&quot;/topic/&quot;, &quot;/queue/&quot;);
        config.setApplicationDestinationPrefixes(&quot;/app&quot;);
    }

    /**
     * 
     * Configure the {@link org.springframework.messaging.MessageChannel} used
     * for incoming messages from WebSocket clients. By default the channel is
     * backed by a thread pool of size 1. It is recommended to customize thread
     * pool settings for production use.
     */
    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {

    }

    /**
     * Configure the {@link org.springframework.messaging.MessageChannel} used
     * for outgoing messages to WebSocket clients. By default the channel is
     * backed by a thread pool of size 1. It is recommended to customize thread
     * pool settings for production use.
     */
    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.taskExecutor().corePoolSize(4).maxPoolSize(10);
    }

}

&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Handling WebSocket [ws(s)://] Requests&lt;/h3&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Handling WebSocket requests is similar to handling regular http(s) requests in Spring based code. We create a regular Spring Controller &lt;b&gt;WebSocketBroadcastController&lt;/b&gt; but use the messaging
      annotations (e.g. @MessageMapping) to handle requests and serve content. Take a look at the &lt;a href=&quot;http://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/index.html?org/springframework/messaging/handler/annotation/MessageMapping.html&quot; target=&quot;_blank&quot;&gt;Spring docs&lt;/a&gt; for more
      details. &lt;br /&gt;
&lt;br /&gt;
Here is the &lt;b&gt;WebSocketBroadcastController&lt;/b&gt; class with self explanatory source code comments. &lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-java&quot;&gt;    
/**
 * Copyright &amp;amp;copy; Sunit Katkar (sunitkatkar@gmail.com) http://sunitkatkar.blogspot.com
 */
package com.blogspot.sunitkatkar.controllers;

import java.security.Principal;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.stereotype.Controller;

import com.blogspot.sunitkatkar.model.MessageBroadcast;
import com.blogspot.sunitkatkar.model.SimpleMessage;
import com.blogspot.sunitkatkar.util.Util;

/**
 * {@link WebSocketBroadcastController} is a regular Spring Controller as seen
 * in most Spring MVC applications. Its job is to receive {@link SimpleMessage}
 * message objects from the client, extract the &amp;lt;code&amp;gt;payload&amp;lt;/code&amp;gt; (or
 * contents) of the message, prepend it with some simple text and finally
 * broadcast (or publish) the message to all clients who have subscribed to the
 * &amp;lt;code&amp;gt;/topic/simplemessages&amp;lt;/code&amp;gt; message queue.
 * 
 * 
 * @author &amp;lt;a href=&quot;mailto:sunitkatkar@gmail.com&quot;&amp;gt;Sunit Katkar&amp;lt;/a&amp;gt;
 * @since 1.0
 * @version 1.0.0.1
 */

@Controller
public class WebSocketBroadcastController {

    private static final Logger LOG = LoggerFactory
            .getLogger(WebSocketBroadcastController.class);

    /**
     * Method to handle the requests sent to this controller at
     * &amp;lt;code&amp;gt;/simplemessages&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;
     * &amp;lt;br/&amp;gt;
     * &amp;lt;b&amp;gt;Explanation:&amp;lt;/b&amp;gt; The &amp;lt;code&amp;gt;@MessageMapping&amp;lt;/code&amp;gt; annotation ensures
     * that if a message is sent to destination &amp;lt;code&amp;gt;/simplemessages&amp;lt;/code&amp;gt;,
     * then the
     * {@link WebSocketBroadcastController#processMessageFromClient(SimpleMessage)}
     * method is called. &amp;lt;br/&amp;gt;
     * &amp;lt;br/&amp;gt;
     * The message payload is bound to the {@link SimpleMessage} object. For
     * simplicity, this method simulates a 3 second delay before sending back
     * the message as a {@link MessageBroadcast} object. The return value is
     * broadcast to all subscribers to
     * &amp;lt;code&amp;gt;/topic/simplemessagesresponse&amp;lt;/code&amp;gt; as specified in the
     * &amp;lt;code&amp;gt;@SendTo&amp;lt;/code&amp;gt; annotation. &amp;lt;br/&amp;gt;
     * &amp;lt;br/&amp;gt;
     * &amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; The 3 second delay demonstrates that after the server
     * receives a message from the client, the client is free to continue any
     * other processing while the server takes its own time to act on the
     * received message.
     * 
     * @param message
     * @param principal
     * @param locale
     * @return
     * @throws Exception
     */
   &lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;@MessageMapping(&quot;/simplemessages&quot;)&lt;/pre&gt;
&lt;pre class=&quot;prettyprint&quot; id=&quot;quine&quot; style=&quot;border: 2px solid #990000;&quot;&gt;@SendTo(&quot;/topic/simplemessagesresponse&quot;)&lt;/pre&gt;
public MessageBroadcast processMessageFromClient(SimpleMessage message,
            Principal principal) throws Exception {
        // Simulate a delay of 3 seconds
        Thread.sleep(3000);
        LOG.info(&quot;Sending server side response &#39;{}&#39; for user: {}&quot;, message,
                principal.getName());
        return new MessageBroadcast(&quot;Server response: Did you send &amp;amp;lt;b&amp;amp;gt;&#39;&quot;
                + message.getMessage() + &quot;&#39;&amp;amp;lt;/b&amp;amp;gt;? (Server Response at: &quot;
                + Util.getSimpleDate() + &quot;)&quot;);
    }

    /**
     * If there are any exceptions thrown by any of the messaging infrastructure
     * then they can be sent to the end user on the &amp;lt;code&amp;gt;/queue/errors&amp;lt;/code&amp;gt;
     * destination.
     * 
     * @param exception
     * @return
     */
    @MessageExceptionHandler
    @SendToUser(&quot;/queue/errors&quot;)
    public String handleException(Throwable exception) {
        return exception.getMessage();
    }
}
    &lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Client Side WebSockets Code - basickWebsockets.jsp&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
On the client side we will use the SockJS javascript library to create a WebSocket connection and then communicate with the server. The following jsp page &lt;b&gt;basicWebsockets.jsp&lt;/b&gt; has the HTML
      and Javascript together for easier reading. Note that I have used Twitter Bootstrap and hence there is some javascript code to handle the UI interactions. You can create a bare bones HTML page
      too. &lt;br /&gt;
&lt;br /&gt;
The code has self explanatory comments.
      &lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums=true lang-xml&quot;&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&amp;gt;
&amp;lt;%@ taglib uri=&#39;http://java.sun.com/jsp/jstl/core&#39; prefix=&#39;c&#39;%&amp;gt;
&amp;lt;!-- basicWebsockets.jsp --&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot;&amp;gt;
&amp;lt;meta http-equiv=&quot;Cache-Control&quot; content=&quot;no-store, no-cache, must-revalidate, max-age=0&quot;&amp;gt;
&amp;lt;!--  Bootstrap related --&amp;gt;
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
&amp;lt;!-- Latest compiled and minified Bootstrap CSS --&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;&amp;lt;c:url value=&quot;/resources/scripts/bootstrap/css/bootstrap.min.css&quot;/&amp;gt;&quot;&amp;gt;
&amp;lt;title&amp;gt;Learn WebSockets 1&amp;lt;/title&amp;gt;
&amp;lt;!-- WebSocket related javascript includes --&amp;gt;
&amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/sockjs-0.3.4.min.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/stomp.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;noscript&amp;gt;
    &amp;lt;h2 style=&quot;color: #ff0000&quot;&amp;gt;Seems your browser doesn&#39;t support Javascript! WebSocket relies on Javascript being enabled. Please enable Javascript and reload this page!&amp;lt;/h2&amp;gt;
  &amp;lt;/noscript&amp;gt;
  &amp;lt;c:url var=&quot;imageUrl&quot; value=&quot;/resources/images/user01.png&quot; /&amp;gt;
  &amp;lt;div class=&quot;container&quot;&amp;gt;
    &amp;lt;div class=&quot;row&quot;&amp;gt;
      &amp;lt;div class=&quot;col-sm-10&quot;&amp;gt;
        &amp;lt;!-- WebSocket related Twitter Bootstrap 3.0 based UI elements --&amp;gt;
        &amp;lt;div id=&quot;heading&quot; class=&quot;masthead&quot;&amp;gt;
          &amp;lt;div class=&quot;pull-right&quot;&amp;gt;
            Logged In: &amp;lt;strong&amp;gt;${username}&amp;lt;/strong&amp;gt; | ${time } | &amp;lt;a href=&quot;${pageContext.request.contextPath}/logout&quot;&amp;gt;Logout&amp;amp;nbsp;&amp;lt;span class=&quot;glyphicon glyphicon-remove&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;h3 class=&quot;muted&quot;&amp;gt;
            &amp;lt;img src=&quot;${imageUrl}&quot; /&amp;gt;Welcome to Learning WebSockets 1
          &amp;lt;/h3&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;row&quot;&amp;gt;
      &amp;lt;div class=&quot;col-sm-6&quot;&amp;gt;
        &amp;lt;p&amp;gt;&amp;amp;nbsp;&amp;lt;/p&amp;gt;
        &amp;lt;!-- Connect and Disconnect buttons to establish/terminate a connection to the websocket service --&amp;gt;
        &amp;lt;div class=&quot;panel&quot;&amp;gt;
          &amp;lt;button id=&quot;connect&quot; class=&quot;btn btn-success btn-sm&quot;&amp;gt;Connect&amp;lt;/button&amp;gt;
          &amp;lt;button id=&quot;disconnect&quot; class=&quot;btn btn-danger btn-sm&quot;&amp;gt;Disconnect&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;p /&amp;gt;
        &amp;lt;div class=&quot;panel panel-default&quot;&amp;gt;
          &amp;lt;div class=&quot;panel-heading&quot;&amp;gt;Send Messages To WebSocket Server&amp;lt;/div&amp;gt;
          &amp;lt;div class=&quot;panel-body&quot; id=&quot;conversationDiv&quot;&amp;gt;
            &amp;lt;div class=&quot;input-group&quot;&amp;gt;
              &amp;lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;txtSendMessage&quot; placeholder=&quot;Enter message&quot;&amp;gt; &amp;lt;span class=&quot;input-group-btn&quot;&amp;gt;
                &amp;lt;button id=&quot;sendMessage&quot; class=&quot;btn btn-primary&quot;&amp;gt;
                  &amp;lt;span class=&quot;glyphicon glyphicon-share-alt&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;amp;nbsp;Send
                &amp;lt;/button&amp;gt;
              &amp;lt;/span&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;!-- Error alert --&amp;gt;
            &amp;lt;div class=&quot;alert alert-danger alert-dismissable&quot; id=&quot;formAlert&quot;&amp;gt;
              &amp;lt;button type=&quot;button&quot; class=&quot;close&quot; data-dismiss=&quot;alert&quot; aria-hidden=&quot;true&quot;&amp;gt;&amp;amp;times;&amp;lt;/button&amp;gt;
              &amp;lt;strong&amp;gt;Error!&amp;lt;/strong&amp;gt; Message cannot be blank.
            &amp;lt;/div&amp;gt;
            &amp;lt;!-- /Error alert --&amp;gt;
            &amp;lt;!-- Info alert --&amp;gt;
            &amp;lt;div class=&quot;alert alert-info alert-dismissable&quot; id=&quot;formInfoAlert&quot;&amp;gt;
              &amp;lt;button type=&quot;button&quot; class=&quot;close&quot; data-dismiss=&quot;alert&quot; aria-hidden=&quot;true&quot;&amp;gt;&amp;amp;times;&amp;lt;/button&amp;gt;
              &amp;lt;strong&amp;gt;Message Sent!&amp;lt;/strong&amp;gt; &amp;lt;br /&amp;gt;Your message has been sent to the server. You can continue to do other actions. Server response will be shown when it arrives.
            &amp;lt;/div&amp;gt;
            &amp;lt;!-- /Info alert --&amp;gt;
            &amp;lt;!-- .input-group --&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;!-- .panel-body --&amp;gt;
          &amp;lt;div class=&quot;panel-body&quot; id=&quot;response&quot;&amp;gt;&amp;lt;/div&amp;gt;
          &amp;lt;!-- Div to show the server responses --&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;!-- .panel --&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;!-- .container --&amp;gt;
  &amp;lt;!-- External Javascripts --&amp;gt;
  &amp;lt;!-- Latest compiled and minified JQuery JavaScript (necessary for Bootstrap&#39;s JavaScript plugins). Placed at the end of the document so the pages load faster --&amp;gt;
  &amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/jquery-1.10.2.min.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;!-- Include all compiled plugins (below), or include individual files as needed --&amp;gt;
  &amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/bootstrap/js/bootstrap.min.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;!-- Knockout data-binding MVVM library. More at http://knockoutjs.com/  --&amp;gt;
  &amp;lt;script src=&quot;&amp;lt;c:url value=&quot;/resources/scripts/knockout-3.0.0.js&quot;/&amp;gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;%-- URL for the STOMP end point for registering a stomp client--%&amp;gt;
  &amp;lt;c:url value=&quot;/simplemessages&quot; var=&quot;socketDest&quot; /&amp;gt;
  &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
            /***********************************************/
            /* PLEASE READ UP ON STOMP AND SOCKJS          */
            /* 1) http://jmesnil.net/stomp-websocket/doc/  */
            /* 2) https://github.com/sockjs/sockjs-client  */
            /***********************************************/

            //Declare a stompclient which will connect to the server
            var stompClient = null;

            /************************************************************************** 
            /*  JQUERY WAY OF BEING UNOBTRUSIVE AND ADDING EVENT HANDLERS TO WIDGETS, 
            /*  THUS KEEPING HTML AND JAVASCRIPT SEPARATE 
            /*************************************************************************/
            // Runs this code only when the DOM (all elements) are ready
            $(document).ready(function() {
                // On page load the text input field &#39;MESSAGE&#39;, &#39;DISCONNECT&#39; and &#39;SEND&#39; buttons 
                // should all be disabled as user has not clickedd &#39;CONNECT&#39; button yet.
                $(&quot;#disconnect&quot;).prop(&#39;disabled&#39;, true);
                $(&quot;#txtSendMessage&quot;).prop(&#39;disabled&#39;, true);
                $(&quot;#sendMessage&quot;).prop(&#39;disabled&#39;, true);

                //Also all text in server message should be empty
                $(&quot;#txtSendMessage&quot;).val(&quot;&quot;);
                //Remove any server responses from previous interactions
                $(&quot;#response&quot;).empty();
                //Hide the validation and info alerts on page load
                $(&quot;.alert&quot;).hide();
                // Event handler: Connect button
                $(&quot;#connect&quot;).on(&quot;click&quot;, function(e) {
                    // If alert is visible, hide it
                    $(&quot;#formAlert&quot;).slideUp(400);
                    connect();
                });

                // Event handler: Disconnect button 
                $(&quot;#disconnect&quot;).on(&quot;click&quot;, function(e) {
                    // If alert is visible, hide it
                    $(&quot;#formAlert&quot;).slideUp(400);
                    disconnect();
                });
                // Event handler: X button on top right of info alert.
                // Clicking the X button on top right will dismiss it from the screen and hide it
                $(&quot;.alert&quot;).find(&quot;.close&quot;).on(&quot;click&quot;, function(e) {
                    // Find all elements with the &quot;alert&quot; class, get all descendant elements 
                    // with the class &quot;close&quot;, and bind a &quot;click&quot; event handler

                    // Don&#39;t allow the click to bubble up the DOM
                    e.stopPropagation();

                    // Don&#39;t let any default functionality occur (in case it&#39;s a link)
                    e.preventDefault();

                    // Hide this specific Alert
                    $(this).closest(&quot;.alert&quot;).slideUp(400);

                    // Focus on the Send Message textfield
                    $(&quot;#txtSendMessage&quot;).select();
                    $(&quot;#txtSendMessage&quot;).focus();
                });

                // Event handler: Send button
                $(&quot;#sendMessage&quot;).on(&quot;click&quot;, function(e) {

                    // Find the input text element for the server message
                    var messageForServer = $(&quot;#txtSendMessage&quot;).val();

                    if (messageForServer === &quot;&quot;) {

                        // If message is empty prevent submission and show the alert
                        e.preventDefault();
                        $(&quot;#formAlert&quot;).slideDown(400);

                    } else {

                        // Message is not empty so send to server
                        $(&quot;#formAlert&quot;).slideUp(400);

                        // Show a please wait alert
                        $(&quot;#formInfoAlert&quot;).slideDown(400);

                        // Send message to server. The message for the server must 
                        // be in JSON format. 
                        // Also refer SimpleMessage.java POJO.
                        sendMessageToServer(messageForServer);
                    }
                });
            });

            //Function sets the state of the Connect and Disconnect buttons
            function setConnected(connected) {
                //Since we are using bootstrap, this is how you disable buttons 
                // and input widgets
                $(&quot;#connect&quot;).prop(&#39;disabled&#39;, connected);
                $(&quot;#disconnect&quot;).prop(&#39;disabled&#39;, !connected);
                $(&quot;#sendMessage&quot;).prop(&#39;disabled&#39;, !connected);
                $(&quot;#txtSendMessage&quot;).prop(&#39;disabled&#39;, !connected)
            }

            // Function to connect the web client to the websocket server
            function connect() {
                //Remove any server responses from previous interactions
                $(&quot;#response&quot;).empty();
                //Also all text in server message input field should be empty
                $(&quot;#txtSendMessage&quot;).val(&quot;&quot;);
                $(&quot;#txtSendMessage&quot;).focus();
                $(&quot;#txtSendMessage&quot;).select();
                // Register a websocket endpoint using SockJS and stomp.js
                // Refer to Java class Refer to Java class 
                // WebSocketConfig.java#registerStompEndpoints(StompEndpointRegistry registry)
                var socket = new SockJS(&#39;${socketDest}&#39;);
                stompClient = Stomp.over(socket);
                // Now that a stomp client is defined, its time to open a connection
                // 1) First we connect to the websocket server
                // Notice that we dont pass in username and password as Spring Security
                // has already provided the server with the Principal object containing user credentials
                // 2) The last argument is a callback function which is called when connection succeeds
                stompClient.connect(&#39;&#39;, &#39;&#39;, function(frame) {
                    //set the connect and disconnect button state. (disable connect button)
                    setConnected(true);
                    // In production code remove the next line
                    console.log(&quot;Connected: &quot; + frame);
                    //Lets show a connection success message
                    showServerBroadcast(&quot;Connection established: &quot; + frame, false);
                    // Now subscribe to a topic of interest.
                    // Refer to Java class WebsocketBroadcastController.java#processMessageFromClient(SimpleMessage message)
                    // WebsocketBroadcastController is waiting for connections. Upon successful connection, it subscribes to
                    // the &quot;/topic/simplemessagesresponse&quot; destination where the server will echo the messages.
                    // When a broadcast message is received by the client on that destination, it will be shown by appending
                    // a paragraph to the DOM in the client browser.
                    stompClient.subscribe(&quot;/topic/simplemessagesresponse&quot;, function(servermessage) {//Callback when server responds
                        showServerBroadcast(JSON.parse(servermessage.body).messageContent, false);
                        //Server responded so hide the info alert
                        $(&quot;#formInfoAlert&quot;).slideUp(400);
                        //Also all text in server message input field should be empty
                        $(&quot;#txtSendMessage&quot;).val(&quot;&quot;);
                        $(&quot;#txtSendMessage&quot;).focus();
                        $(&quot;#txtSendMessage&quot;).select();
                    });
                });
            }

            // Function to disconnect the web client to the websocket server
            function disconnect() {
                //First hide any alerts
                $(&quot;#formAlert&quot;).slideUp(400);
                $(&quot;#formInfoAlert&quot;).slideUp(400);
                // Disconnect the stompClient
                stompClient.disconnect();
                // Set the connect and disconnect button states
                setConnected(false);
                // In production remove the next line
                console.log(&quot;Disconnected&quot;);
                showServerBroadcast(&quot;WebSocket connection is now terminated!&quot;, true);
            }

            // Function to send the message typed in by the user to the &quot;/app/simplemessages&quot; destination on the server.
            // WebsocketBroadcastController will receive this message and broadcast the results after 
            // an artificially introduced delay.
            function sendMessageToServer(messageForServer) {
                //Show on the browser page that a message is being sent
                showServerBroadcast(&quot;Your message &#39;&quot; + messageForServer + &quot;&#39; is being sent to the server.&quot;, true);
                // The message for the server must be in JSON format. Also refer SimpleMessage.java POJO.
                stompClient.send(&quot;/app/simplemessages&quot;, {}, JSON.stringify({
                    &#39;message&#39; : messageForServer
                }));
            }

            /**
             * Function to show the server response on the web page
             * @param servermessage - text to be shown on webpage
             * @param localMessage - boolean, if true then it means its a 
             *                       client side javascript generated message.
             */
            function showServerBroadcast(servermessage, localMessage) {
                // Server surrounds the user sent message with &amp;lt;b&amp;gt; and &amp;lt;/b&amp;gt; 
                // as &amp;amp;ltb&amp;amp;gt;message%lt;/b&amp;amp;gt;
                // Use Jquery to decode the HTML and show it as &amp;lt;b&amp;gt;message&amp;lt;/b&amp;gt;
                var decoded = $(&quot;&amp;lt;div/&amp;gt;&quot;).html(servermessage).text();

                var tmp = &quot;&quot;;
                var serverResponse = document.getElementById(&quot;response&quot;);
                var p = document.createElement(&#39;p&#39;);
                p.style.wordWrap = &#39;break-word&#39;;

                if (localMessage) {
                    p.style.color = &#39;#006600&#39;;
                    tmp = &quot;&amp;lt;span class=&#39;glyphicon glyphicon-dashboard&#39;&amp;gt;&amp;lt;/span&amp;gt; &quot; + decoded + &quot; (Browser time:&quot; + getCurrentDateTime() + &quot;)&quot;;
                } else {
                    p.style.color = &#39;#8A0808&#39;;
                    tmp = &quot;&amp;lt;span class=&#39;glyphicon glyphicon-arrow-right&#39;&amp;gt;&amp;lt;/span&amp;gt; &quot; + decoded;
                }
                //Assigning the decoded HTML to the &amp;lt;p&amp;gt; element
                p.innerHTML = tmp;
                serverResponse.appendChild(p);
            }

            /**
             * Utility function to return the date time in simple format
             * like Tue Jan 07 2014 @ 11:47:24 AM
             */
            function getCurrentDateTime() {
                var date = new Date();
                var n = date.toDateString();
                var time = date.toLocaleTimeString();
                return n + &quot; @ &quot; + time;
            }
        &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;    
    &lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
The Final Result&lt;/h4&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Download the project (link at the end of this post) and run it.&lt;br /&gt;
&lt;br /&gt;
You can access the WebSockets app in the browser at the url &lt;b&gt;http://localhost:8080/learn-websockets-1&lt;/b&gt;. Happy WebSocket-ing :)
    
     &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihzbnp7KtxiC8r1tTlYJCOBhTRXat5WleVuo1eZF2QtXD34lgDMlVdRB7V5b4h-U_r2TY03x3rYuMdy8vlvdhuh6N3jCdhsCkThgarZqUUhSLW5tCL74E7B8dCwBm4czXG0JScLDiIOYLw/s1600/web-browser-01.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihzbnp7KtxiC8r1tTlYJCOBhTRXat5WleVuo1eZF2QtXD34lgDMlVdRB7V5b4h-U_r2TY03x3rYuMdy8vlvdhuh6N3jCdhsCkThgarZqUUhSLW5tCL74E7B8dCwBm4czXG0JScLDiIOYLw/s320/web-browser-01.png&quot; height=&quot;236&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGIm9ONpZekkxV0cdjR5YzeQqzpd2cIrNXgf4UVrWuGf_Ztugo9X8pJ3nBn8q79q0c8Si_HdiZZNg7eKT42zp7Ky24bUVgmE1YCOvZnE0k7ZF0-3atkGdnV1ywr4v_KjeaZwLpvUk1md4X/s1600/web-browser-02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGIm9ONpZekkxV0cdjR5YzeQqzpd2cIrNXgf4UVrWuGf_Ztugo9X8pJ3nBn8q79q0c8Si_HdiZZNg7eKT42zp7Ky24bUVgmE1YCOvZnE0k7ZF0-3atkGdnV1ywr4v_KjeaZwLpvUk1md4X/s320/web-browser-02.png&quot; height=&quot;154&quot; style=&quot;background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUoYmDBvi35A0pLqLbTd7th0vr7yoiuLExQOMmEMobjz0-y2mo2HN_t8cxM40lQieUIbFcvJGpOuJdgia6h_fpMD6rOOBzTyCHX5gqRcak1iej14LpIHCIEcWix4PupXku27U0XGq9fG71/s1600/web-browser-03.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUoYmDBvi35A0pLqLbTd7th0vr7yoiuLExQOMmEMobjz0-y2mo2HN_t8cxM40lQieUIbFcvJGpOuJdgia6h_fpMD6rOOBzTyCHX5gqRcak1iej14LpIHCIEcWix4PupXku27U0XGq9fG71/s320/web-browser-03.png&quot; height=&quot;154&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtxVrReyJXy7JSI1ADG7v_LESiZPMRa7TvrjZGIjN5uUysvOIWKbXA1isQ4RV53KxCoW4UKmq1vPYzhI_ozV6EWa82vgqRRGIdP02iBAKNkbiAWPQX-z1SsovNdhn2dA0mfWfmJxlSnzbB/s1600/web-browser-04.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtxVrReyJXy7JSI1ADG7v_LESiZPMRa7TvrjZGIjN5uUysvOIWKbXA1isQ4RV53KxCoW4UKmq1vPYzhI_ozV6EWa82vgqRRGIdP02iBAKNkbiAWPQX-z1SsovNdhn2dA0mfWfmJxlSnzbB/s320/web-browser-04.png&quot; height=&quot;172&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxqBH7PnvFrIO84fRPBO__T5JiZhhsnNVLZEOcvsFnT460oWTQsl1hznvnnm44QS2NP-_KofCDyyNQLVKhfyrV156nbnU_jEMC8GmnUwqkhabxm-7cYFFqECLR4_JS0PvfPsP9zI6MTswN/s1600/web-browser-05.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxqBH7PnvFrIO84fRPBO__T5JiZhhsnNVLZEOcvsFnT460oWTQsl1hznvnnm44QS2NP-_KofCDyyNQLVKhfyrV156nbnU_jEMC8GmnUwqkhabxm-7cYFFqECLR4_JS0PvfPsP9zI6MTswN/s320/web-browser-05.png&quot; height=&quot;172&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvzF0M64j5EIGvI4wiLOKLoOn0BAdRLd4lqc8r60X-8SylEzj4WENTukcxH1Ur0NY5pD5flAgjX_kVcoTFHl7jMfTYB_UfMjJqTvazw8c1wC7ZQ5_uuiondNmD2rHni1eDl2SQJ3SdrxGw/s1600/web-browser-06.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvzF0M64j5EIGvI4wiLOKLoOn0BAdRLd4lqc8r60X-8SylEzj4WENTukcxH1Ur0NY5pD5flAgjX_kVcoTFHl7jMfTYB_UfMjJqTvazw8c1wC7ZQ5_uuiondNmD2rHni1eDl2SQJ3SdrxGw/s320/web-browser-06.png&quot; height=&quot;172&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBFb7bA4fhCmwUQkUWmbAqiAZXMPXqvwCOP4a4GBs5dvn9TVu01btTu6Gxusb1ScPa8wSmFjPLTKl1i4huzWAKbe-QySg-R23BgbGSt6sjjvhLhGhrW7kUqNkkkumJ9pbZ88oB5WryLqCM/s1600/web-browser-07.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBFb7bA4fhCmwUQkUWmbAqiAZXMPXqvwCOP4a4GBs5dvn9TVu01btTu6Gxusb1ScPa8wSmFjPLTKl1i4huzWAKbe-QySg-R23BgbGSt6sjjvhLhGhrW7kUqNkkkumJ9pbZ88oB5WryLqCM/s320/web-browser-07.png&quot; height=&quot;277&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Download the app from &lt;a href=&quot;https://drive.google.com/file/d/0B4h_K1-o-MSUajdmSEt4R2tpZTA/edit?usp=sharing&quot; target=&quot;_blank&quot;&gt;this location&lt;/a&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><link>http://sunitkatkar.blogspot.com/2014/01/spring-4-websockets-with-sockjs-stomp.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0Mq2ZYvuw1-EK31jSedwnmN8v4nQzxpQgSXzWl0OP3y56YO_QWIWraBs8u-TvCX97EDa_uip4DPj173R31wUa6taNEyJMlGdVLjHc72ZWcTWq0I09dxDPruSP4Gk6_n7a-vkPOE-d6Y2V/s72-c?imgmax=800" height="72" width="72"/><thr:total>16</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-1343475119083468375</guid><pubDate>Mon, 01 Apr 2013 10:17:00 +0000</pubDate><atom:updated>2014-01-15T04:55:47.822-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">progress</category><category domain="http://www.blogger.com/atom/ns#">progress bar</category><category domain="http://www.blogger.com/atom/ns#">thread</category><category domain="http://www.blogger.com/atom/ns#">threads</category><category domain="http://www.blogger.com/atom/ns#">update</category><category domain="http://www.blogger.com/atom/ns#">vb.net</category><category domain="http://www.blogger.com/atom/ns#">visual studio</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><title>Using Threads in VB.Net for showing a progress bar in a separate dialog</title><description>&lt;script src=&quot;https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?autoload=true&amp;skin=default&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://google-code-prettify.googlecode.com/svn/loader/lang-vb.js&quot;&gt;&lt;/script&gt;
&lt;style&gt;
.prettyprint ol.linenums&gt;li {
 list-style-type: decimal; 
 !
 important
}
&lt;/style&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
I am new to VB.NET. I had programmed in Visual Basic 4 many many years ago. Recently I had to use Visual Studio 2010 to create a quick application for internal usage. Now there was a task which took a long time. As per good user interface design it was obvious that a progress update should be shown to keep the end user informed and updated till the task completed.&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
To cut a long story short, the requirement was to let the long running task continue while a progress bar showed the progress of the task. After searching for examples, I got a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms171728(v=vs.100).aspx&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;basic idea&lt;/a&gt; on how to use threads in VB.Net to accomplish the task I had at hand.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUkDB7Kw-Iwcqvy4aEe47ElpIcycWbkhXL4EYdRAa1Ol3IushgvjylB6ujgSAbRLMuEiLa74nWwlB4D7uIZL5KfGZ5rbHlO3H2urRCYmX8DgTQgeUSXTD1pDrRpzs3WXboApTL0DQv4huN/s1600/ProgressBarVB-MainForm.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUkDB7Kw-Iwcqvy4aEe47ElpIcycWbkhXL4EYdRAa1Ol3IushgvjylB6ujgSAbRLMuEiLa74nWwlB4D7uIZL5KfGZ5rbHlO3H2urRCYmX8DgTQgeUSXTD1pDrRpzs3WXboApTL0DQv4huN/s1600/ProgressBarVB-MainForm.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
Fig. 1 Main Dialog&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2M_gVbK-G84wLKxj2ZFvx6RyZv_zHsg-vSZrgBw7kV_8EivoA4-3i0j4hJo2oxwPA5ax7OJR-QNsRY60Ti3jV1mr91KS18lCLAhsl16h8SscSvjMYgTfUFl0FACcCvjxzAByjOwKnUK0F/s1600/ProgressBarVB-ProgressDialog.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;110&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2M_gVbK-G84wLKxj2ZFvx6RyZv_zHsg-vSZrgBw7kV_8EivoA4-3i0j4hJo2oxwPA5ax7OJR-QNsRY60Ti3jV1mr91KS18lCLAhsl16h8SscSvjMYgTfUFl0FACcCvjxzAByjOwKnUK0F/s320/ProgressBarVB-ProgressDialog.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&amp;nbsp; Fig. 2 Separately Launched Progress Dialog&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I have attached the VS2010 project for you to download and see the code. The main working parts are explained here.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;b&gt;Basic Steps&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Step 1 - Create a basic Windows Form application&lt;/li&gt;
&lt;li&gt;Step 2 - Create a simple Dialog and add a ProgressBar and a Label to it&lt;/li&gt;
&lt;li&gt;Step 3 - Write a method which will launch a separate Thread to perform the long running task&lt;/li&gt;
&lt;li&gt;Step 4 - Write Delegate methods in the Dialog&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The code is self explanatory.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Code for the Main Form&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-vb linenums&quot;&gt;
Option Explicit On
Option Strict On

Imports System.Threading

&#39; Main form which launches a long running task and 
&#39; shows progress update in a separate dialog
Public Class MainForm
    Inherits Form

    &#39;Flag that indcates if a process is running
    Dim isProcessRunning As Boolean = False

    &#39;Progress bar dialog
    Dim progressDlg As New ProgressDialog


    &#39;Long running background process with 
    &#39;a determinate progress indicator, 
    &#39;using a seperate modal dialog containing
    &#39;a progress bar

    &amp;lt;MTAThread()&amp;gt; _
    Private Sub ButtonClick1_Click(ByVal sender As System.Object, _
                                   ByVal e As System.EventArgs) _
                               Handles ButtonClick1.Click

        &#39;If a process is already running, 
        &#39;warn the user and cancel the operation
        If isProcessRunning = True Then
            MessageBox.Show(&quot;Sorry, a process is already running.&quot;, _
                            &quot;Status&quot;, MessageBoxButtons.OK, _
                            MessageBoxIcon.Exclamation)
            Return
        End If

        &#39;Define a background thread and start the 
        &#39;long running process in this separate thread
        Dim backgroundThread As _
            New Threading.Thread(AddressOf DoLongRunningProcess)

        &#39; Start the background process thread
        backgroundThread.Start()

        &#39; Open the dialog
        progressDlg.Show()
    
End Sub

     
    &#39; The long running process 

    Public Sub DoLongRunningProcess()
        &#39; Set the flag that indicates if a 
        &#39; process is currently running
        isProcessRunning = True
        
        &#39; Iterate from 0 - 100
        &#39; On each iteration, pause the thread 
        &#39; for .05 seconds, then update the 
        &#39; dialog&#39;s progress bar
        For n As Integer = 0 To 100
            Thread.Sleep(100)
            progressDlg.UpdateProgress(n)
        Next
        
        &#39; Show a dialog box that confirms the process 
        &#39; has completed
        MessageBox.Show(&quot;Thread completed!&quot;, &quot;Status&quot;, _
                        MessageBoxButtons.OK, _
                        MessageBoxIcon.Information)
        &#39;Close the dialog when user clicks OK
        progressDlg.Close()
        &#39; Reset the flag that indicates if a process is
        &#39; currently running
        isProcessRunning = False
    End Sub
  
End Class
&lt;/pre&gt;
&lt;div&gt;
&lt;b&gt;Code for the Progress Dialog&lt;/b&gt;&lt;/div&gt;
 
&lt;pre class=&quot;prettyprint linenums lang-vb&quot;&gt;
Option Explicit On
Option Strict On
Imports System.Windows.Forms
  
&#39; Dialog class with a ProgressBar widget to 
&#39; show the progress of a long running task
 
Public Class ProgressDialog
    Inherits Form

    &#39; Delegate to update the progress 
    &#39; of the ProgressBar widget
    Delegate Sub DelegateUpdate(ByVal progress As Integer)
   
    &#39; Delegate to handle the Close event 
    &#39; for this dialog
    Delegate Sub DelegateClose(ByRef dialog As Form)

    &#39; Default constructor which initializes 
    &#39; this control
    Public Sub New()
        InitializeComponent()
    End Sub


    
    &#39; Method to update the progress bar widget. This 
    &#39; uses the InvokeRequired and BeginInvoke methods
    Public Sub UpdateProgress(ByVal progress As Integer)
        If ProgressBar1.InvokeRequired Then
            ProgressBar1.BeginInvoke(New DelegateUpdate(AddressOf UpdateDelegateImpl), progress)
        Else
            ProgressBar1.Value = progress
        End If
    End Sub

    &#39; Overloads the Close method
    Public Overloads Sub Close()
        If Me.InvokeRequired Then
            Me.BeginInvoke(New  _
                           DelegateClose(AddressOf CloseDelegateImpl), Me)
        Else
            Me.Close()
        End If
    End Sub
   
    &#39; Implementation of the DelegateUpdate
    Sub UpdateDelegateImpl(ByVal progress As Integer)
        ProgressBar1.Value = progress
        LabelProgress.Text = &quot;&quot;
        LabelProgress.Text = progress &amp; CStr(&quot;%&quot;)
    End Sub
    
    &#39; Implmentation of the DelegateClose
    Sub CloseDelegateImpl(ByRef dialog As Form)
        dialog.Close()
    End Sub

End Class
&lt;/pre&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;b&gt;Download Project&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I have uploaded the project as a ZIP archive on Google Drive. &lt;a href=&quot;https://docs.google.com/file/d/0B4h_K1-o-MSUYXFtOWpxWldsXzQ/edit?usp=sharing&quot; target=&quot;_blank&quot;&gt;Click to download&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;</description><link>http://sunitkatkar.blogspot.com/2013/04/using-threads-in-vbnet-for-showing.html</link><author>noreply@blogger.com (Sunit)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUkDB7Kw-Iwcqvy4aEe47ElpIcycWbkhXL4EYdRAa1Ol3IushgvjylB6ujgSAbRLMuEiLa74nWwlB4D7uIZL5KfGZ5rbHlO3H2urRCYmX8DgTQgeUSXTD1pDrRpzs3WXboApTL0DQv4huN/s72-c/ProgressBarVB-MainForm.png" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-6351054748296144198</guid><pubDate>Fri, 21 Jan 2011 23:26:00 +0000</pubDate><atom:updated>2014-01-07T03:33:51.749-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">autocomplete</category><category domain="http://www.blogger.com/atom/ns#">browsing history</category><category domain="http://www.blogger.com/atom/ns#">cache</category><category domain="http://www.blogger.com/atom/ns#">clear cache</category><category domain="http://www.blogger.com/atom/ns#">cookies</category><category domain="http://www.blogger.com/atom/ns#">internet explorer</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>Quickly and selectively clean up your Internet Explorer cache</title><description>&lt;script src=&quot;https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?skin=sunburst&quot;&gt;&lt;/script&gt;
While testing GWT applications it is sometimes necessary to clean up your entire cache. Firefox has simple shortcut keys to achieve this, but IE does not. Especially IE7. (Yes we have to support IE7 as the lowest version)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is a quick way to do it. You can run this from a command prompt, or a batch file or simply from the &#39;Run&#39; menu which pops up when you click Run from the Start menu.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;
#To clear IE7 temporary Internet files 
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 8

#To clear IE7 browsing cookies 
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 2

#To clear IE7 browsing history 
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 1

#To clear IE7 form data 
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 16

#To clear IE7 remembered passwords for filling web login forms 
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 32

#To clear or delete all IE7 browsing history i.e all of the above! 
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 255

&lt;/pre&gt;</description><link>http://sunitkatkar.blogspot.com/2011/01/quickly-and-selectively-clean-up-your.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-2708665558736468130</guid><pubDate>Wed, 07 Oct 2009 21:00:00 +0000</pubDate><atom:updated>2009-10-07T14:01:05.508-07:00</atom:updated><title>Testing Windows Live Writer to post to my blog</title><description>&lt;p&gt;Just testing how Windows Live Writer works to post directly to my blog. Apparently it works just fine :)&lt;/p&gt;  </description><link>http://sunitkatkar.blogspot.com/2009/10/testing-windows-live-writer-to-post-to.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-4439725235922902795</guid><pubDate>Tue, 23 Jun 2009 17:21:00 +0000</pubDate><atom:updated>2009-06-23T10:21:59.702-07:00</atom:updated><title>Looking at BlackBerry as a development platform</title><description>I found an &lt;a href=&quot;http://www.versatilemonkey.com/story.html&quot;&gt;interesting article&lt;/a&gt; about experiences of developing for the BlackBerry.</description><link>http://sunitkatkar.blogspot.com/2009/06/looking-at-blackberry-as-development.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-2206854507416405012</guid><pubDate>Thu, 11 Jun 2009 17:44:00 +0000</pubDate><atom:updated>2009-06-11T10:50:51.717-07:00</atom:updated><title>Should I take the plunge into iPhone development?</title><description>I have been delaying getting into iPhone Application development. I had so many ideas for developing applications for the mobile device. Android definitely helped me get a feel of what it takes to develop mobile apps. My last experience developing for a hand held device was with Palm OS 3.0 with Code Warrior IDE about a decade ago. After that Android has been my only foray into mobile development.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The reason I feel that I should finally give in to iPhone is that I dont see much traction for Android applications. The market place and success stories of iPhone developers lure me more towards it. The other reason is that I want to keep my skills current and relevant. When Palm Pre was to be released there was much excitement in the developer community, but now it seems to have fizzled out. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I want to be able to learn an exciting new platform and also look at it in a slightly commerical light. Why should I not be able to translate my efforts to dollars?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My biggest mental block to iPhone is perhaps the requirements where I have to get a Mac. I have always been a developer who has used Windows and Linux to quite an extent.  I have only used a Mac for maybe an hour or so in my entire career.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Or should I look into Symbian? It has a Windows based development environment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyone out there who has some experience with this? Please share your thoughts.&lt;/div&gt;</description><link>http://sunitkatkar.blogspot.com/2009/06/should-i-take-plunge-into-iphone.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-8705900385123588320</guid><pubDate>Wed, 17 Dec 2008 19:27:00 +0000</pubDate><atom:updated>2008-12-17T11:51:51.592-08:00</atom:updated><title>Android SendMail - Send Email Programmatically</title><description>&lt;span style=&quot;color: #1c2023; font-family: &#39;Lucida Grande&#39;; font-size: 13px;&quot;&gt;&lt;div style=&quot;line-height: 1.5; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;SendMail is really an excellent email program found on most Unix systems. I just borrowed the name for my tutorial on sending email programmatically from an Android phone.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.5; margin-bottom: 1em; margin-left: 0px; margin-right: 0px; margin-top: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;Long ago, when I worked on the Palm OS, one could create an email message programmatically, and then place it in the Outbox of the Email application. Once the PDA was synced with the PC, the email would be sent. I was looking for a similar way to send email from the Android phone. After searching the google groups and scouring websites and android docs, I managed to piece together a &lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;http://www.vidyut.com/sunit/android/android_sendmail.html&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;simple example.&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;</description><link>http://sunitkatkar.blogspot.com/2008/12/sendmail-send-email-programmatically.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>18</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-1115412505133875950</guid><pubDate>Sat, 01 Nov 2008 18:05:00 +0000</pubDate><atom:updated>2008-12-17T16:01:55.553-08:00</atom:updated><title>Tipster on the real Android G phone</title><description>&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:small;&quot;&gt;I finally got a chance to run the &lt;/span&gt;&lt;a href=&quot;http://www.vidyut.com/sunit/android/index.html&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:small;&quot;&gt;Tipster application&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:small;&quot;&gt; on a real Android powered T-Mobile G phone. I realised that you have to slide open the keyboard to enter values, thus changing the view into a &#39;landscape mode&#39;. When you do that, the results of the tip calculations are not visible as they are towards the bottom half of the screen. So I experimented and found that I needed to allow &#39;scrolling&#39; of the view. I have updated the the tutorial with the &lt;a href=&quot;http://www.vidyut.com/sunit/android/tipster_enhancement1.html&quot;&gt;simple enhancements&lt;/a&gt; to make the application visible even in landscape mode.&lt;/span&gt;&lt;/span&gt;</description><link>http://sunitkatkar.blogspot.com/2008/11/tipster-on-real-android-g-phone.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-1576269824894092746</guid><pubDate>Sat, 01 Nov 2008 02:44:00 +0000</pubDate><atom:updated>2008-10-31T19:59:22.599-07:00</atom:updated><title>Some folks are really cowards!</title><description>&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;Just today I got hold of a G1 phone. As I was searching the Android App Market, what do I see? I see that some person by the name &lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 153);&quot;&gt;&#39;Steve Coward&#39;&lt;/span&gt; has &lt;a href=&quot;http://www.vidyut.com/sunit/android/index.html&quot;&gt;copied my tutorial&lt;/a&gt; and packaged it as his own! He has published it as Tip Calculator on the App Market for free download.&lt;br /&gt;&lt;br /&gt;I dont mind people using my source code, but I had expressly written in the source code that please dont redistribute this code! &lt;br /&gt;&lt;br /&gt;At the very least he could have given some credit to me!&lt;br /&gt;&lt;br /&gt;I really feel that some folks dont get the meaning of tutorials, helping hands, requests to not do certain things. Very unethical!&lt;/span&gt;</description><link>http://sunitkatkar.blogspot.com/2008/10/some-folks-are-pathetic-losers.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-523151633387570637.post-5398284838413272567</guid><pubDate>Wed, 15 Oct 2008 23:30:00 +0000</pubDate><atom:updated>2008-12-17T11:31:42.970-08:00</atom:updated><title>How to develop applications for the Google Android OS</title><description>&lt;div&gt;&lt;/div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: small;&quot;&gt;Recently I started exploring the Google Android OS for mobile phones. It is quite an interesting OS and a joy to develop for. I have written this tutorial which shows you how you can write a simple &lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;http://www.vidyut.com/sunit/android/index.html&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: small;&quot;&gt;Tip Calculator&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: small;&quot;&gt; application for your Google Android powered phone.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;</description><link>http://sunitkatkar.blogspot.com/2008/10/how-to-develop-applications-for-google.html</link><author>noreply@blogger.com (Sunit)</author><thr:total>13</thr:total></item></channel></rss>