<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Spring Boot &#8211; Pauls Blog</title>
	<atom:link href="https://sterl.org/category/java/spring-boot/feed/" rel="self" type="application/rss+xml" />
	<link>https://sterl.org</link>
	<description></description>
	<lastBuildDate>Mon, 09 Jun 2025 13:08:19 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>Spring Persistent Tasks</title>
		<link>https://sterl.org/2025/04/spring-persistent-tasks/</link>
					<comments>https://sterl.org/2025/04/spring-persistent-tasks/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sun, 20 Apr 2025 07:16:43 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[dashboard]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Inbound Pattern]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Outbound Pattern]]></category>
		<category><![CDATA[Quartz]]></category>
		<category><![CDATA[quartz daschboard]]></category>
		<category><![CDATA[scheduled]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[task ui]]></category>
		<category><![CDATA[task-scheduling]]></category>
		<category><![CDATA[Transaction]]></category>
		<category><![CDATA[trigger]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1116</guid>

					<description><![CDATA[A simple task management framework designed to queue and execute asynchronous tasks with support for database persistence and a user-friendly interface. It can be used to implement scheduling patterns or outbound patterns. Focus is the usage with spring boot and JPA. https://github.com/sterlp/spring-persistent-tasks Key Features]]></description>
										<content:encoded><![CDATA[
<p>A simple task management framework designed to queue and execute asynchronous tasks with support for database persistence and a user-friendly interface. It can be used to implement scheduling patterns or outbound patterns.</p>



<p>Focus is the usage with spring boot and JPA.</p>



<p><a href="https://github.com/sterlp/spring-persistent-tasks">https://github.com/sterlp/spring-persistent-tasks</a></p>



<h2 class="wp-block-heading">Key Features</h2>



<ol class="wp-block-list">
<li><strong>JPA-Powered Persistence</strong>&nbsp;&#8211; Automatically persists tasks to your database</li>



<li><strong>Spring Boot Auto-Configuration</strong>&nbsp;&#8211; Simple setup with @EnableSpringPersistentTasks</li>



<li><strong>Clustering Support</strong>&nbsp;&#8211; Built-in lock management for distributed environments</li>



<li><strong>Type-Safe Tasks</strong>&nbsp;&#8211; Generic task definitions with state objects</li>



<li><strong>Retry Mechanisms</strong>&nbsp;&#8211; Automatic retry policies for failed executions</li>



<li><strong>Transactional Integration</strong>&nbsp;&#8211; Works with Spring&#8217;s transaction management</li>



<li><strong>Queue Management</strong> &#8211; Intelligent task queuing and prioritization</li>



<li><strong>Different DB Supports</strong> 
<ul class="wp-block-list">
<li>MsSQL</li>



<li>MariaDB</li>



<li>Postgres</li>
</ul>
</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2025/04/spring-persistent-tasks/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Transaktionsmanagement mit Spring, JPA, Hibernate</title>
		<link>https://sterl.org/2024/08/transaktionsmanagement-mit-spring-jpa-hibernate/</link>
					<comments>https://sterl.org/2024/08/transaktionsmanagement-mit-spring-jpa-hibernate/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sat, 31 Aug 2024 15:02:17 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[@Transactional]]></category>
		<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[Grundlagen Datenbanken]]></category>
		<category><![CDATA[Grundlagen Transaktionen]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Mandatory]]></category>
		<category><![CDATA[Read only transaction]]></category>
		<category><![CDATA[Required]]></category>
		<category><![CDATA[Spring Data]]></category>
		<category><![CDATA[Spring TransactionTemplate]]></category>
		<category><![CDATA[Transaction Timeout]]></category>
		<category><![CDATA[Transactions]]></category>
		<category><![CDATA[TransactionTemplate]]></category>
		<category><![CDATA[Transkationen]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=1032</guid>

					<description><![CDATA[Lerne die Grundlagen des Transaktionsmanagements in modernen Datenbanken kennen, und erfahre, wie du mit Spring Boot, Spring Data, JPA und Hibernate effektiv arbeitest. In diesem Tutorial starten wir mit den Grundlagen der Datenbanktransaktionen in deiner Anwendung: &#8211; Transaktionen starten: Dieses Video ist perfekt für Entwickler, die ihre Fähigkeiten in Spring Framework erweitern und transaktionssichere Anwendungen&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Lerne die Grundlagen des Transaktionsmanagements in modernen Datenbanken kennen, und erfahre, wie du mit Spring Boot, Spring Data, JPA und Hibernate effektiv arbeitest.</p>



<p>In diesem Tutorial starten wir mit den Grundlagen der Datenbanktransaktionen in deiner Anwendung: &#8211; Transaktionen starten: </p>



<ul class="wp-block-list">
<li><strong>Transaktion starten</strong>: Verstehe, wie Du Transaktionen in Spring Boot richtig initialisierst.</li>



<li><strong>Rollback-Strategien:</strong> Erlerne die wichtigsten Methoden, um Transaktionen bei Fehlern sicher zurückzusetzen. </li>



<li><strong>Annotations</strong>: Setze Annotations gezielt ein, um Transaktionen zu steuern. </li>



<li><strong>Programmatische Transaktionen</strong>: Implementiere Transaktionen programmatisch und gewinne maximale Kontrolle. </li>



<li><strong>Read Only</strong>: Transaktionen für GET Operationen </li>



<li><strong>Timeouts</strong>: Wie stelle ich bei einer Transaktion einen Timeout ein, was muss ich beachten?</li>
</ul>



<p>Dieses Video ist perfekt für Entwickler, die ihre Fähigkeiten in Spring Framework erweitern und transaktionssichere Anwendungen erstellen möchten.</p>



<ul class="wp-block-list">
<li><a href="https://github.com/sterlp/youtube/commit/24f1d4e1576be803ec32142ffb84f438dcd30623">Git Commit</a></li>



<li><a href="https://github.com/sterlp/youtube/tree/main/db-grundlagen">Git Projekt</a></li>
</ul>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Transaktionsmanagement | Datenbanken | Spring Boot &amp; Data, JPA &amp; Hibernate | @Transactional" width="640" height="360" src="https://www.youtube.com/embed/9cY73uCj5wA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/08/transaktionsmanagement-mit-spring-jpa-hibernate/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Setup Spring Boot Azure OAuth2 with CORS</title>
		<link>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/</link>
					<comments>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Thu, 01 Feb 2024 09:03:03 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[CORS error]]></category>
		<category><![CDATA[oauth2Login]]></category>
		<category><![CDATA[OAuth2UserService]]></category>
		<category><![CDATA[strict-origin-when-cross-origin]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=993</guid>

					<description><![CDATA[What is needed Setup an Azure AAD Application First we need an Azure AAD application which gives us the access to our AD users. The important part are the client id and the tenant id here: Add the web URIs which are allowed to use the OAuth2 login In the next step we have to&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">What is needed</h2>



<ol class="wp-block-list">
<li>Setup an Azure AAD Application</li>



<li>Add the web URIs which are allowed to use the OAuth2 login</li>



<li>Add a client secret for your application</li>



<li>Add API Permission to read the profile</li>



<li>Add needed Azure dependencies</li>



<li>Setup Spring OAuth config</li>



<li>Adjust the CORS settings in Spring to ensure token refreshes</li>



<li>Configure spring security</li>
</ol>



<h2 class="wp-block-heading">Setup an Azure AAD Application</h2>



<p>First we need an Azure AAD application which gives us the access to our AD users. The important part are the client id and the tenant id here:</p>



<figure class="wp-block-image size-full is-resized"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png"><img fetchpriority="high" decoding="async" width="810" height="243" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png" alt="" class="wp-image-1004" style="aspect-ratio:3.3333333333333335;width:840px;height:auto" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png 810w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-300x90.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-768x230.png 768w" sizes="(max-width: 810px) 100vw, 810px" /></a></figure>



<h2 class="wp-block-heading">Add the web URIs which are allowed to use the OAuth2 login</h2>



<p>In the next step we have to allow &#8222;applications&#8220; based on their &#8222;DNS&#8220; name to access and login through this AAD. Ensure to remember the yellow part, which is later needed in the configutation.</p>



<p>The URLs are basically the one you whitelist for a login. If you setup the &#8222;test&#8220; AAD application you may want also add sometimes the localhost for testing. Ensure to remove it again later on.</p>



<figure class="wp-block-image size-large"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication.png"><img decoding="async" width="1024" height="493" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-1024x493.png" alt="" class="wp-image-1006" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-1024x493.png 1024w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-300x144.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-768x369.png 768w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication.png 1368w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">Add a client secret for your application</h2>



<p>Next we have to create a secret for our application, we only require later the value of it. Please make sure you provide a new one after the expiration period.</p>



<p>You can have multiple secrets for multiple apps here.</p>



<figure class="wp-block-image size-large"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret.png"><img loading="lazy" decoding="async" width="1024" height="317" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-1024x317.png" alt="" class="wp-image-1009" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-1024x317.png 1024w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-300x93.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-768x238.png 768w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret.png 1439w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">Setup Spring OAuth config</h2>



<p>In this configuration we have to enter all the collected data <strong>azure-dev</strong> as name is here the suffix provided in the authentication section of the Azure AAD application. You can choose what ever name you like.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;yaml&quot;,&quot;mime&quot;:&quot;text/x-yaml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;YAML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;yaml&quot;}">spring:
  security:
    oauth2:
      client:
        provider:
          azure:
            issuer-uri: https://login.microsoftonline.com/&lt;Directory (tenant) ID&gt;/v2.0
            user-name-attribute: name
        registration:
          azure-dev:
            provider: azure
            client-id: &lt;Application (client) ID&gt;
            client-secret: &lt;the secret value you created for your app&gt;
            client-authentication-method: client_secret_post
            scope:
              - openid
              - email
              - profile</pre></div>



<h2 class="wp-block-heading">Spring Security</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">  @Bean
  SecurityFilterChain filterChain(HttpSecurity http, OptionalYourUserService userService) throws Exception {
    // @formatter:off
    http
      .authorizeHttpRequests(authorizeHttpRequests -&gt;
        authorizeHttpRequests
          // public URLs
          .requestMatchers(antMatcher(&quot;/actuator/health/readiness&quot;)).permitAll()
          // secure actuator
          .requestMatchers(antMatcher(&quot;/actuator/**&quot;)).hasRole(UserGroup.ADMIN)
          // app urls
          .requestMatchers(&quot;/api/**&quot;).authenticated()
          // default; recommended to use .authenticated()
          .anyRequest().permitAll()
      ).headers(headers -&gt; headers.frameOptions(FrameOptionsConfig::sameOrigin))
      .oauth2Login( oauth2 -&gt; oauth2
          .userInfoEndpoint(userInfo -&gt; userInfo
            .oidcUserService(oidcUserService(userService)))
      )
      .headers(headers -&gt; headers.frameOptions(FrameOptionsConfig::sameOrigin));
    // @formatter:on
    return http.build();
  }

  private OAuth2UserService&lt;OidcUserRequest, OidcUser&gt; oidcUserService(
    OptionalYourUserService userService) {
    return userRequest -&gt; {
      var oidcUser = new OidcUserService().loadUser(userRequest); // Delegate to the default
                                                                  // implementation
      
      // add any custom user service integration here, if required.

      return oidcUser;
    };
  }</pre></div>



<h2 class="wp-block-heading">Add CORS Config</h2>



<p>To avoid any <code>CORS error</code> / <code>strict-origin-when-cross-origin</code> in your application we have to whitelist the OAuth2 provider for any redirect, in this example login.microsoft:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">  @Bean
  protected CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList(&quot;https://login.microsoftonline.com/**&quot;));
    configuration.addAllowedHeader(&quot;*&quot;);
    configuration.addAllowedMethod(&quot;*&quot;);
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration(&quot;/**&quot;, configuration);
    return source;
  }</pre></div>



<h2 class="wp-block-heading">Links</h2>



<ul class="wp-block-list">
<li>https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Datenbank&#124; Transaktionen &#124; Isolationlevel &#124; Locks &#124; Hibernate &#124; JPA &#124; Spring Boot</title>
		<link>https://sterl.org/2023/10/datenbank-transaktionen-isolationlevel-locks-hibernate-jpa-spring-boot/</link>
					<comments>https://sterl.org/2023/10/datenbank-transaktionen-isolationlevel-locks-hibernate-jpa-spring-boot/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Mon, 02 Oct 2023 11:40:50 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[DB Locks]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Isolationlevel]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Transaktionen]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=958</guid>

					<description><![CDATA[Um weiterführende Konzepte besser nachvollziehen zu können, wollen wir uns in den Grundlagen Datenbanken mit Spring Boot, Isolation Level (Isolationsgrad) und Locks beschäftigen.]]></description>
										<content:encoded><![CDATA[
<p>Um weiterführende Konzepte besser nachvollziehen zu können, wollen wir uns in den Grundlagen Datenbanken mit Spring Boot, Isolation Level (Isolationsgrad) und Locks beschäftigen.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Datenbanken Grundlagen | Transaktionen | Isolation Level | Locks | Hibernate | JPA | Spring Boot" width="640" height="360" src="https://www.youtube.com/embed/6ytlI4Sshjc?start=604&#038;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2023/10/datenbank-transaktionen-isolationlevel-locks-hibernate-jpa-spring-boot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Disable @Scheduled timers for test in Spring</title>
		<link>https://sterl.org/2022/05/disable-scheduled-timers-for-test-in-spring/</link>
					<comments>https://sterl.org/2022/05/disable-scheduled-timers-for-test-in-spring/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Mon, 02 May 2022 09:18:37 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[@Scheduled]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[timer]]></category>
		<category><![CDATA[Unit Test]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=770</guid>

					<description><![CDATA[Problem As soon we have timers in our project they may cause issues in our integration tests, as they start running in the most undesirable situation. E.g. during the trigger a specific function which would usually be triggered by the timer. Solution 1 If we want to disable the timers even the construction of the&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>As soon we have timers in our project they may cause issues in our integration tests, as they start running in the most undesirable situation. E.g. during the trigger a specific function which would usually be triggered by the timer.</p>



<h2 class="wp-block-heading">Solution 1</h2>



<p>If we want to disable the timers even the construction of the beans we have to tell spring not event to lead the beans. To achieve that we require first some configuration. As we might have more than one timer it is easier to work with an own meta annotaton</p>



<h3 class="wp-block-heading">Own Meta annotation</h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Java&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@ConditionalOnProperty(name = &quot;my-project.timers-enabled&quot;, 
                       havingValue = &quot;true&quot;, 
                       matchIfMissing = true)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
public @interface TimersEnabled {

}</pre></div>



<h3 class="wp-block-heading">Use the annotation</h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Java&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@TimersEnabled
@Component
@RequiredArgsConstructor
public class MyTimer {
    
    private final MyService service;

    @Scheduled(fixedDelay = 30, timeUnit = TimeUnit.SECONDS)
    void scheduledMethod() {
        service.doStuff();
    }
}</pre></div>



<h3 class="wp-block-heading">Disable the timers</h3>



<p>e.g. in the <code>application.yml</code> of your test resources:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;yaml&quot;,&quot;mime&quot;:&quot;text/x-yaml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;YAML&quot;,&quot;language&quot;:&quot;YAML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;yaml&quot;}">my-project:
  timers-enabled: false</pre></div>



<p>The timers will be disabled for any value other then <code>true</code>. </p>



<h2 class="wp-block-heading">Solution 2</h2>



<p>In the easiest scenario if it is a in memory Spring test we can just mock the <code>ScheduledExecutorService</code> and so stop any <code>@Scheduled</code> job executions.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">    @MockBean
    private ScheduledExecutorService schedulerService;</pre></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2022/05/disable-scheduled-timers-for-test-in-spring/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>JPA Model testing with Hibernate Statistics</title>
		<link>https://sterl.org/2021/08/jpa-model-testing-with-hibernate-statistics/</link>
					<comments>https://sterl.org/2021/08/jpa-model-testing-with-hibernate-statistics/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sun, 01 Aug 2021 11:25:00 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Statistics]]></category>
		<category><![CDATA[Unit Test]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=925</guid>

					<description><![CDATA[Problem Often we write JPA Entity classes an have to ensure in a larger team that refactoring doesn&#8217;t create performance problems or logical errors in the entity model usual problems are: In your test]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>Often we write JPA Entity classes an have to ensure in a larger team that refactoring doesn&#8217;t create performance problems or logical errors in the entity model usual problems are:</p>



<ul class="wp-block-list">
<li>Missing fetch joins in Queries
<ul class="wp-block-list">
<li>Which leads to slow fetch joins</li>
</ul>
</li>



<li>Wrong direction of Entity relations 
<ul class="wp-block-list">
<li>which leads to updates after inserts</li>



<li>or even to deletes and reinserts of data</li>
</ul>
</li>



<li>Wrong transaction boundaries
<ul class="wp-block-list">
<li>Which leads to multiple transactions for one logical business operation</li>
</ul>
</li>
</ul>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@Component
public class HibernateAsserts {
  private final Statistics statistics;

  public HibernateAsserts(EntityManager entityManager) {
    try (Session session = entityManager.unwrap(org.hibernate.Session.class)) {
      @SuppressWarnings(&quot;resource&quot;)
      SessionFactory factory = session.getSessionFactory();
      factory.getStatistics().setStatisticsEnabled(true);
      statistics = factory.getStatistics();
    }
  }
  
  public HibernateAsserts assertTrxCount(int expected) {
    long value = statistics.getTransactionCount();
    if (value != expected) {
      logSummary();
      fail(&quot;Expected &quot; + expected + &quot; TransactionCount, but found &quot; + value);
    }
    return this;
  }
  
  public HibernateAsserts assertInsertCount(int expected) {
    long value = statistics.getEntityInsertCount();
    if (value != expected) {
      logSummary();
      fail(&quot;Expected &quot; + expected + &quot; EntityInsertCount, but found &quot; + value);
    }
    return this;
  }

  public void reset() {
    statistics.clear();
  }

  public void logSummary() {
    statistics.logSummary();
  }
}</pre></div>



<h2 class="wp-block-heading">In your test</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@SpringBootTest
class MyTestClassTest {

  @Autowired private SubjectUnderTest subject;
  @Autowired private HibernateAsserts hibernateAsserts;
  
  @Test
  void textMyBusinessMethod() {
    // GIVEN
    // custom data setup for the test

    // WHEN
    hibernateAsserts.reset(); // ensure the setup is not in the stats
    subject.runBusinessMethod();
    
    // THEN
    // any business asserts
    hibernateAsserts
      .assertTrxCount(1)
      .assertInsertCount(1);
  }
}</pre></div>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2021/08/jpa-model-testing-with-hibernate-statistics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Aspects with Annotations</title>
		<link>https://sterl.org/2021/05/aspects-with-annotations/</link>
					<comments>https://sterl.org/2021/05/aspects-with-annotations/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Mon, 24 May 2021 09:28:46 +0000</pubDate>
				<category><![CDATA[AOP]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[aspect]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=655</guid>

					<description><![CDATA[Problem Define a pointcut for annotated methods. The most example are based only on @within or @annotation which has the downside that the aspect is added to all methods and the check of the annotation is executed during runtime. Solution Git Repository https://github.com/sterlp/training/tree/master/aspect Links https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html https://docs.spring.io/spring-framework/docs/5.3.x/reference/html/core.html#aop-pointcuts-designators]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>Define a pointcut for annotated methods. The most example are based only on <code>@within</code> or <code>@annotation</code> which has the downside that the aspect is added to all methods and the check of the annotation is executed during runtime. </p>



<h2 class="wp-block-heading">Solution</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@Aspect
@Component
public class MethodAspect {
    /**
     * This ensures that the aspect is only woven into methods with the annotation.
     * Otherwise all methods are woven!
     */
    @Pointcut(&quot;execution(@MethodAnnotation * * (..))&quot;)
    private void isAnnotated() {};
    /**
     * (optional) Limit package scan to our project only
     */
    @Pointcut(&quot;execution(* your.project.package..*(..))&quot;)
    private void isInPackage() {};

    @Around(&quot;isAnnotated() &amp;&amp; isInPackage() &amp;&amp; @annotation(annotation)&quot;)
    public Object logExecutionTime(ProceedingJoinPoint joinPoint, 
                                   MethodAnnotation annotation) throws Throwable {
        return joinPoint.proceed();
    }
}</pre></div>



<h2 class="wp-block-heading">Git Repository</h2>



<p><a href="https://github.com/sterlp/training/tree/master/aspect">https://github.com/sterlp/training/tree/master/aspect</a></p>



<h2 class="wp-block-heading">Links</h2>



<ul class="wp-block-list"><li><a href="https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html">https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html</a></li><li><a href="https://docs.spring.io/spring-framework/docs/5.3.x/reference/html/core.html#aop-pointcuts-designators">https://docs.spring.io/spring-framework/docs/5.3.x/reference/html/core.html#aop-pointcuts-designators</a></li></ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2021/05/aspects-with-annotations/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Spring Boot Redirect to SwaggerUI</title>
		<link>https://sterl.org/2021/05/spring-boot-redirect-to-swaggerui/</link>
					<comments>https://sterl.org/2021/05/spring-boot-redirect-to-swaggerui/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Fri, 21 May 2021 13:13:33 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[OpenAPI]]></category>
		<category><![CDATA[Swagger]]></category>
		<category><![CDATA[swagger-ui]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=650</guid>

					<description><![CDATA[Problem Some services don&#8217;t have an UI and the OpenAPI/ Swagger UI should be used as default UI of the service. As so the root should be redirected directly to the SwaggerUI. Solution Just add a WebMvc redirect. Swagger Open API dependencies Spring Boot 2.x Ensure you check the current version: Spring Boot 3.x Ensure&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>Some services don&#8217;t have an UI and the OpenAPI/ Swagger UI should be used as default UI of the service. As so the root should be redirected directly to the SwaggerUI.</p>



<h2 class="wp-block-heading">Solution</h2>



<p>Just add a WebMvc redirect.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@Configuration
public class OpenApiConfig implements WebMvcConfigurer {
  @Override
  public void addViewControllers(final ViewControllerRegistry registry) {
    registry.addRedirectViewController(&quot;/&quot;, &quot;/swagger-ui.html&quot;);
    // use setStatusCode(HttpStatus.XYZ) for any custom status code if required, e.g. MOVED_PERMANENTLY
    registry.addRedirectViewController(&quot;/swagger-ui&quot;, &quot;/swagger-ui.html&quot;);
    // any other alias
  }
}</pre></div>



<h3 class="wp-block-heading">Swagger Open API dependencies</h3>



<h4 class="wp-block-heading">Spring Boot 2.x</h4>



<p>Ensure you <a href="https://central.sonatype.com/search?q=springdoc-openapi-ui&amp;namespace=org.springdoc" target="_blank" rel="noreferrer noopener">check the current version</a>: </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;xml&quot;,&quot;mime&quot;:&quot;application/xml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;XML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;xml&quot;}">        &lt;dependency&gt;
            &lt;groupId&gt;org.springdoc&lt;/groupId&gt;
            &lt;artifactId&gt;springdoc-openapi-ui&lt;/artifactId&gt;
            &lt;version&gt;1.7.0&lt;/version&gt;
        &lt;/dependency&gt;
       &lt;!-- if spring security is used --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springdoc&lt;/groupId&gt;
            &lt;artifactId&gt;springdoc-openapi-security&lt;/artifactId&gt;
            &lt;version&gt;1.7.0&lt;/version&gt;
        &lt;/dependency&gt;</pre></div>



<h4 class="wp-block-heading">Spring Boot 3.x</h4>



<p>Ensure you <a href="https://central.sonatype.com/search?q=springdoc-openapi-starter-webmvc-ui&amp;namespace=org.springdoc" target="_blank" rel="noreferrer noopener">check the current version</a>:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;xml&quot;,&quot;mime&quot;:&quot;application/xml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;XML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;xml&quot;}">        &lt;dependency&gt;
            &lt;groupId&gt;org.springdoc&lt;/groupId&gt;
            &lt;artifactId&gt;springdoc-openapi-starter-webmvc-ui&lt;/artifactId&gt;
            &lt;version&gt;2.1.0&lt;/version&gt;
        &lt;/dependency&gt;</pre></div>



<p>With the new version you can also use the <code>application.yml</code> to configure the root directory as swagger ui:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;yaml&quot;,&quot;mime&quot;:&quot;text/x-yaml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;YAML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;yaml&quot;}">springdoc:
  swagger-ui:
    use-root-path: true</pre></div>



<h2 class="wp-block-heading">Links</h2>



<ul class="wp-block-list">
<li><a rel="noreferrer noopener" href="https://springdoc.org/" target="_blank">https://springdoc.org/</a></li>



<li><a href="https://springdoc.org/v2/">https://springdoc.org/v2/</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2021/05/spring-boot-redirect-to-swaggerui/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Reconnecting JMS listener</title>
		<link>https://sterl.org/2020/04/reconnecting-jms-listener/</link>
					<comments>https://sterl.org/2020/04/reconnecting-jms-listener/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sat, 04 Apr 2020 13:34:15 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[JMS]]></category>
		<category><![CDATA[Reconnect]]></category>
		<guid isPermaLink="false">http://sterl.org/?p=558</guid>

					<description><![CDATA[Problem In some projects we still may need to manually to reconnect to our JMS provider. For what ever reason the framework or the container cannot do the job for us. As so we have to ensure that an once registered JMS listener re-register itself if something bad happens. Note: Check first if your container&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>In some projects we still may need to manually to reconnect to our JMS provider. For what ever reason the framework or the container cannot do the job for us. As so we have to ensure that an once registered JMS listener re-register itself if something bad happens.</p>



<div class="bs-callout bs-callout-info"><strong>Note:</strong>
Check first if your container can handle this for you.
</div>



<h2 class="wp-block-heading">Solution</h2>



<p>Well some <code>JmsConnectionFactory</code> already support a re-connection but they are not always very reliable. For instance, the <a rel="noreferrer noopener" href="https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/com.ibm.mq.ref.dev.doc/q111980_.htm" target="_blank">IBM driver supports</a> in theory a reconnect, but it is just a bit buggy.</p>



<p>Well, what is the straight forward solution? The most easiest way is just to register an exception listener with the connection and rebuild the connection from here:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}"> connection.setExceptionListener((e) -&gt; {
   connection = cf.createConnection();
   session = connection.createSession();
   consumer = session.createConsumer(session.createQueue(&quot;FANCY.QUEUE.NAME&quot;));
   consumer.setMessageListener((m) -&gt; {
     System.out.println(&quot;onMessage: &quot; + m);
   }
   connection.start();
 });
</pre></div>



<p>Not clean but in theory, this is all that we have to do. Of course, we have to handle the state, the old connection and even worse think about a retry if the connection cannot be created immediately again. The last part considering that we have of course also the requirement to stop the connection and avoid race conditions is the hard part.</p>



<h3 class="wp-block-heading">ReconnectinListener</h3>



<p>Let us build a <code>ReconnectingListener</code> step by step. What we have seen above is that we need a way to determine the desired connection state and we have to provide separate methods for <code>connect </code>and <code>disconnect </code>as we will do this more often, in case we have to retry to re-connect again.</p>



<h4 class="wp-block-heading">Connecting and Disconnecting</h4>



<p>Lets us first solve the connect and disconnect problem. The user should be able to:</p>



<ol class="wp-block-list"><li>Have a separate connect method</li><li>Store the user desire if we should be connected or not</li><li>Have a separate disconnect method</li><li>Have a way to clear the resources without to reset the user desire</li><li>Have a way to check if the connection is up and running</li></ol>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@RequiredArgsConstructor
static class ReconnectingListener implements MessageListener,  ExceptionListener {
    final JmsConnectionFactory cf;
    final String destinationQueue;
    
    private Connection connection;
    private Session session;
    private MessageConsumer consumer;
    // 1. Have a separate connect method
    public synchronized void connect() throws JMSException {
        // 2. Store the user desire if we should be connected or not
        shouldRun.set(true);
        if (!isConnected()) {
            connection = cf.createConnection();
            session = connection.createSession();
            consumer = session.createConsumer(session.createQueue(destinationQueue));
            consumer.setMessageListener(this); // register us
            connection.setExceptionListener(this); // react on errors
            connection.start();
        }
    }
    // 3. Have a separate disconnect method 
    public synchronized void disconnect() {
        // 2. Store the user desire if we should be connected or not
        shouldRun.set(false);
        clearConnection();
    }
    // 4. Have a way to clear the resources without to reset the user desire
    private synchronized void clearConnection() {
        JmsUtil.close(consumer);
        JmsUtil.close(session);
        JmsUtil.close(connection);
        consumer = null;
        session = null;
        connection = null;
        LOG.debug(&quot;Connection cleared and stoped&quot;);
   }
   // 5. Have a way to check if the connection is up and running
   public boolean isConnected() {
       return connection != null &amp;&amp; consumer != null &amp;&amp; session != null;
   }</pre></div>



<h4 class="wp-block-heading">Reconnect &#8222;onException&#8220;</h4>



<p>Having solved this we have to re-connect back to the JMS Broker if we lose the connection. For this have to implement the <code>ExceptionListener </code>interface as shown above and now to implement <code>onException</code>.  The goal here is now:</p>



<ol class="wp-block-list"><li>Clear the old connection to avoid a double registration</li><li>Schedule a delayed retry to connect again</li><li>Check if we still should be connected</li><li>Retry again, if we fail in our retry to connect to the broker</li></ol>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">// we need a executer to delay a retry attempt
private final ScheduledExecutorService reconnectScheduler = Executors.newScheduledThreadPool(1);
@Override
public void onException(JMSException exception) {
    // 1. Clear the old connection to avoid a double registration
    clearConnection();
    // 2. Schedule a delayed retry to connect again
    reconnect(5);
}
private void reconnect(final int delay) {            
    reconnectScheduler.schedule(() -&gt; {
        // 3. Check if we still should be connected
        if (shouldRun.get()) {
            try {
                // here we use our connect method from above
                connect();
            } catch (Exception e) {
                // 4. Retry again, if we fail in our retry to connect to the broker
                LOG.info(&quot;Reconnect failed, will retry in {}s. {}&quot;, delay, e.getMessage());
                clearConnection(); // just for savety
                reconnect(delay);
            }
        }
    }, delay, TimeUnit.SECONDS);
}</pre></div>



<p>That&#8217;s it. Basically we solved all basic requirements </p>



<h3 class="wp-block-heading">Going further</h3>



<p>We should of course provide the ability to set a subscription filter and maybe we should just implement the <code>Closeable </code>interface to provide a more modern API. Not to forget that we have now hardcoded that we subscribe always to a queue, means a way to tell the code if it is a topic or not would be too bad.  Maybe we should also consider using the JMS 2.x API like:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">public synchronized void connectJms2() throws JMSException {
    shouldRun.set(true);
    if (!isConnected()) {
        context = cf.createContext();
        context.setExceptionListener(this);
        context.setAutoStart(true);
        consumer = context.createConsumer(context.createQueue(destinationQueue));
        consumer.setMessageListener(this); // register us
    }
}</pre></div>



<p>Last but not least we could also destroy the executor. Looking forward to a pull request :-).</p>



<h2 class="wp-block-heading">Links</h2>



<ul class="wp-block-list"><li><a rel="noreferrer noopener" href="https://github.com/sterlp/training/blob/master/jms-trainging/src/test/java/org/sterl/training/jms/ibm/IbmReconnectExampleTest.java" target="_blank">Source Code on GitHub</a></li><li><a rel="noreferrer noopener" href="https://docs.oracle.com/cd/E19798-01/821-1751/abljw/index.html" target="_blank">Oracle Docs for connection pool and reconnect for JEE</a></li><li><a href="https://eclipse-ee4j.github.io/glassfish/docs/5.1.0/administration-guide/jms.html" target="_blank" rel="noreferrer noopener">Glassfish Doc</a></li></ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2020/04/reconnecting-jms-listener/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Spring Boot Hateoas JSR Validation</title>
		<link>https://sterl.org/2020/02/spring-boot-hateoas-jsr303-validation/</link>
					<comments>https://sterl.org/2020/02/spring-boot-hateoas-jsr303-validation/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Thu, 06 Feb 2020 16:00:00 +0000</pubDate>
				<category><![CDATA[JSR Validation]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">http://sterl.org/?p=508</guid>

					<description><![CDATA[Problem By default, the JSR 303 Bean validation doesn&#8217;t work together with Spring Boot Data REST HATEOAS. Even worse we are confronted with 500 errors like In our Solutions Imagin in the description that we have a bean-like this and of course a Spring Data repository: Link to the full source code. Solution 1: custom&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>By default, the JSR 303 Bean validation doesn&#8217;t work together with <a href="https://docs.spring.io/spring-data/rest/docs/current/reference/html/#reference" target="_blank" rel="noreferrer noopener" aria-label="Spring Boot Data REST (öffnet in neuem Tab)">Spring Boot Data REST</a> HATEOAS. Even worse we are confronted with 500 errors like</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;JSONxs&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
  &quot;timestamp&quot;: &quot;2020-01-01T20:52:41.336+0000&quot;,
  &quot;status&quot;: 500,
  &quot;error&quot;: &quot;Internal Server Error&quot;,
  &quot;message&quot;: &quot;Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction&quot;,
  &quot;trace&quot;: &quot;org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:543)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:712)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:631)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:385)
....
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [xx.xxx.xxxx.xxx.YourEntity] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='muss zwischen 1 und 1024 liegen', </pre></div>



<h2 class="wp-block-heading">In our Solutions</h2>



<p>Imagin in the description that we have a bean-like this and of course a Spring Data repository:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@Entity @Data
public class ValidatedBean {
    @GeneratedValue
    @Id @Column(updatable = false)
    private Long id;
    @NotNull @Size(min = 2, max = 1024)
    private String name;
}
@RepositoryRestResource(path = &quot;mybean&quot;)
public interface ValidatedBeanDAO extends JpaRepository&lt;ValidatedBean, Long&gt; {}</pre></div>



<p><a href="https://github.com/sterlp/training/tree/master/hateoas-validation">Link to the full source code.</a></p>



<h3 class="wp-block-heading">Solution 1: custom validator</h3>



<p> One way, of course, is to follow the Spring documentation and register validator classes, which intercept the save process. This is <a rel="noreferrer noopener" aria-label="described here (öffnet in neuem Tab)" href="https://docs.spring.io/spring-data/rest/docs/current/reference/html/#validation" target="_blank">described here</a>.</p>



<h4 class="wp-block-heading">Advantages</h4>



<ul class="wp-block-list"><li>Bean is validated before saving it</li><li>No transaction is started</li><li>Maybe cleaner</li></ul>



<h4 class="wp-block-heading">Disadvantages</h4>



<ul class="wp-block-list"><li>Requires the registration of a validator</li><li>Still requires handling of response</li><li>Controller advice needed</li><li>Validation happens twice</li></ul>



<h4 class="wp-block-heading">Solution 1.1: Throw ConstraintViolationException</h4>



<p>The most simple way to achieve this is by using the <code>AbstractRepositoryEventListener</code> and call the validator on your own.</p>



<div class="bs-callout bs-callout-info">
<strong>Note:</strong> Import in this example the <code>javax.validation.Validator</code>.
</div>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@Service
public class HateoasValidationListenerConfig extends AbstractRepositoryEventListener&lt;Object&gt; {

    @Autowired private Validator validator;
    
    @Override
    public void onBeforeSave(Object entity) {
        final Set&lt;ConstraintViolation&lt;Object&gt;&gt; result = validator.validate(entity);
        if (!result.isEmpty()) {
            throw new ConstraintViolationException(result);
        }
    }
    
    @Override
    protected void onBeforeCreate(@Validated Object entity) {
        final Set&lt;ConstraintViolation&lt;Object&gt;&gt; result = validator.validate(entity);
        if (!result.isEmpty()) {
            throw new ConstraintViolationException(result);
        }
    }
}</pre></div>



<p>This will produce by default  the following result:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
  &quot;timestamp&quot;: &quot;2020-01-01T20:56:41.070+0000&quot;,
  &quot;status&quot;: 500,
  &quot;error&quot;: &quot;Internal Server Error&quot;,
  &quot;message&quot;: &quot;name: muss zwischen 2 und 1024 liegen&quot;,
  &quot;trace&quot;: &quot;javax.validation.ConstraintViolationException: name: muss zwischen 2 und 1024 liegen
      at xx.xxx.xxx.HateoasValidationListenerConfig.onBeforeCreate(HateoasValidationListenerConfig.java:29)</pre></div>



<p>Not very &#8222;Springy&#8220; as a Spring validation result and still error code <em>500</em>.  Usually, a Spring validation error looks like:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Spring validation result&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
  &quot;timestamp&quot;: &quot;2020-01-01T20:58:07.957+0000&quot;,
  &quot;status&quot;: 400,
  &quot;error&quot;: &quot;Bad Request&quot;,
  &quot;errors&quot;: [
    {
      &quot;codes&quot;: [
        &quot;Size.ValidatedBean.name&quot;,
        &quot;Size.name&quot;,
        &quot;Size.java.lang.String&quot;,
        &quot;Size&quot;
      ],
      &quot;arguments&quot;: [
        {
          &quot;codes&quot;: [
            &quot;validatedBean.name&quot;,
            &quot;name&quot;
          ],
          &quot;arguments&quot;: null,
          &quot;defaultMessage&quot;: &quot;name&quot;,
          &quot;code&quot;: &quot;name&quot;
        },
        1024,
        2
      ],
      &quot;defaultMessage&quot;: &quot;muss zwischen 2 und 1024 liegen&quot;,
      &quot;objectName&quot;: &quot;validatedBean&quot;,
      &quot;field&quot;: &quot;name&quot;,
      &quot;rejectedValue&quot;: &quot;&quot;,
      &quot;bindingFailure&quot;: false,
      &quot;code&quot;: &quot;Size&quot;
    }
  ],
  &quot;message&quot;: &quot;Validation failed for object='validatedBean'. Error count: 1&quot;,</pre></div>



<h4 class="wp-block-heading">Solution 1.2: Throw Custom Exception</h4>



<p>The problem is, that Spring is still built around the<code>BindingResult</code><strong> </strong>since 2.0, a far older concept &amp; classes as the <code>ConstraintViolation</code> and so doesn&#8217;t provide a default exception mapper for the <code>ConstraintViolationException</code>. Let&#8217;s adjust our solution and use the <code>SpringValidatorAdapter</code>.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@Service
public class HateoasRepositoryValidationListenerConfig extends AbstractRepositoryEventListener&lt;Object&gt; {

    @Autowired private SpringValidatorAdapter validator;

    @Override
    protected void onBeforeCreate(Object entity) {
        BeanPropertyBindingResult errors = new BeanPropertyBindingResult(entity, 
                Introspector.decapitalize(entity.getClass().getSimpleName()));
        validator.validate(entity, errors);
        // throw a custom exception containing the spring validation result
        // which we will use later in our controller exception mapper
        if (errors.hasErrors()) {
            throw new RepositoryListenerValidationException(errors);
        }
    }
    
    @AllArgsConstructor
    public static class RepositoryListenerValidationException extends RuntimeException {
        @Getter
        private final BeanPropertyBindingResult result;
    }
}
</pre></div>



<p>Having this in place we need an exception mapper (<code>@ControllerAdvice</code>) to extract from our <code>BeanPropertyBindingResult</code><strong> </strong>the <code>ObjectError</code>.</p>



<p>As so we have to add to our result first the attributes defined in the <code>DefaultErrorAttributes</code> furthermore by default Spring uses the <code>BindingResult</code><strong> </strong>and so the <code>FieldError</code><strong> </strong>in the <code>errors</code><strong> </strong>attribute to return the validation result.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@ControllerAdvice
public class HateoasJsrErrorExceptionMapper {
  
    @ExceptionHandler(RepositoryListenerValidationException.class)
    public ResponseEntity&lt;Object&gt; handleConstraintViolation(RepositoryListenerValidationException e, ServletWebRequest request) {
        return ResponseEntity.badRequest().body(ValidationError.builder()
                .message(e.getResult().getAllErrors().get(0).getDefaultMessage())
                .path(request.getRequest().getRequestURI())
                .errors(e.getResult().getAllErrors())
                .build());
    }
    
    // Simple model class which represents our DefaultErrorAttributes.
    // The alternative would be to use DefaultErrorAttributes and set the
    // error code etc. in the request
    @Builder @Getter
    @JsonPropertyOrder({&quot;timestamp&quot;, &quot;status&quot;, &quot;error&quot;, &quot;errors&quot;, &quot;message&quot;, &quot;path&quot;})
    @JsonAutoDetect(isGetterVisibility = Visibility.PUBLIC_ONLY, fieldVisibility = Visibility.NONE)
    static class ValidationError {
        final Instant timestamp = Instant.now();
        final String message;
        final String path;
        final List&lt;ObjectError&gt; errors;
        public int getStatus() {
            return HttpStatus.BAD_REQUEST.value();
        }
        public String getError() {
            return HttpStatus.BAD_REQUEST.getReasonPhrase();
        }
    }
}</pre></div>



<p>This will produce the expected result, which is very same as the default Spring validator will produce too.</p>



<h3 class="wp-block-heading">Solution 2: extract cause exception</h3>



<p>Alternatively, we can also extract the root cause of the <code>TransactionSystemException</code>, as the validation has already taken place by hibernate and a <code>ConstraintViolationException</code><strong> </strong>is already attached as root cause.</p>



<h4 class="wp-block-heading">Advantages</h4>



<ul class="wp-block-list"><li>Reuses the validation result from hibernate, validation is executed once</li><li>We may handle other exceptions</li><li>Maybe anyway needed, if we want to catch other DB validation errors like unique constraints</li></ul>



<h4 class="wp-block-heading">Disadvantages</h4>



<ul class="wp-block-list"><li>Maybe somehow hacky?</li><li>DB Transaction is started, not really fail fast</li></ul>



<h4 class="wp-block-heading">Implementation</h4>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Simple Controller Advice&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@ControllerAdvice
public class HateoasJsrErrorExceptionMapper {
    @Autowired
    private MessageSource messageSource;
    
    @ExceptionHandler(TransactionSystemException.class)
    public ResponseEntity&lt;Object&gt; handleConstraintViolation(TransactionSystemException e, WebRequest request) {
        ResponseEntity&lt;Object&gt; result;
        
        if (e.getRootCause() instanceof ConstraintViolationException) {
            ConstraintViolationException cve = (ConstraintViolationException)e.getRootCause();
			// using model class from Spring
            ConstraintViolationExceptionMessage msg = new ConstraintViolationExceptionMessage(
                    cve, messageSource, request.getLocale());
            
            result = ResponseEntity.badRequest().body(msg);
        } else {
            result = null; // not handled here
        }
        return result;
    }
}</pre></div>



<p>In the most simple way, we could, of course, use the Spring <code>ConstraintViolationExceptionMessage</code>, the problem with that is, that the default handler in Spring returns a list of <code>ObjectError</code>, which are just different in structure again.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Result build by the simple controller&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
  &quot;messages&quot;: [
    {
      &quot;message&quot;: &quot;muss zwischen 2 und 1024 liegen&quot;,
      &quot;invalidValue&quot;: &quot;&quot;,
      &quot;entity&quot;: &quot;xx.xx.xxx.ValidatedBean&quot;,
      &quot;property&quot;: &quot;name&quot;
    }
  ],
  &quot;cause&quot;: &quot;Validation failed for classes [xx.xx.xxx.ValidatedBean, messageTemplate='{javax.validation.constraints.Size.message}'}\n]&quot;
}</pre></div>



<h4 class="wp-block-heading">Solution 2.1: Custom ObjectError</h4>



<p>We have basically the same problem as in solution 1, but somehow a bit more tricky. As our source is already a list of <code>ConstraintViolation</code>s. Well straight forward we could add a class which emulates the same structure and map jus the  <code>ConstraintViolation</code>:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Custom model objects&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">// Simpler class representing the fields of the Spring ObjectError
@Getter @ToString
static class SimpleObjectError {
    String defaultMessage;
    String objectName;
    String field;
    Object rejectedValue;
    String code;
    
    public static SimpleObjectError from(ConstraintViolation&lt;?&gt; violation, MessageSource msgSrc, Locale locale) {
        SimpleObjectError result = new SimpleObjectError();
        result.defaultMessage = msgSrc.getMessage(violation.getMessageTemplate(),
                new Object[] { violation.getLeafBean().getClass().getSimpleName(), violation.getPropertyPath().toString(),
                        violation.getInvalidValue() }, violation.getMessage(), locale);
        result.objectName = Introspector.decapitalize(violation.getRootBean().getClass().getSimpleName());
        result.field = String.valueOf(violation.getPropertyPath());
        result.rejectedValue = violation.getInvalidValue();
        result.code = violation.getMessageTemplate();
        return result;
    }
}</pre></div>



<p>But even using this class would produce a result like this:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Spring like response&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
  &quot;timestamp&quot;: &quot;2020-01-01T21:08:21.826429700Z&quot;,
  &quot;status&quot;: 400,
  &quot;error&quot;: &quot;Bad Request&quot;,
  &quot;errors&quot;: [
    {
      &quot;defaultMessage&quot;: &quot;muss zwischen 2 und 1024 liegen&quot;,
      &quot;objectName&quot;: &quot;validatedBean&quot;,
      &quot;field&quot;: &quot;name&quot;,
      &quot;rejectedValue&quot;: &quot;&quot;,
      &quot;code&quot;: &quot;{javax.validation.constraints.Size.message}&quot;
    }
  ],
  &quot;message&quot;: &quot;Validation failed for classes [org.sterl.cloudadmin.impl.identity.model.IdentityBE] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage='muss zwischen 2 und 1024 liegen', propertyPath=name, rootBeanClass=class org.sterl.cloudadmin.impl.identity.model.IdentityBE, messageTemplate='{javax.validation.constraints.Size.message}'}\n]&quot;,
  &quot;path&quot;: &quot;/api/identity&quot;
}</pre></div>



<h4 class="wp-block-heading">Solution 2.2: Bridge and reuse of SpringValidatorAdapter</h4>



<p>A different approach could be to build a small bridge class which would allow us to access the protected method <code>processConstraintViolations</code> in the <code>SpringValidatorAdapter</code>, even if it is maybe a bit dirty:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">// simple bridge to get access to the processConstraintViolations method
static class SpringValidatorBridge extends SpringValidatorAdapter {
    public SpringValidatorBridge(Validator validator) {
        super(validator);
    }
    public BeanPropertyBindingResult processConstraintViolations(ConstraintViolationException cve) {
        // get the bean which was validated
        final Object bean = cve.getConstraintViolations().iterator().next().getRootBean();

        final BeanPropertyBindingResult errors = new BeanPropertyBindingResult(bean, 
                Introspector.decapitalize(bean.getClass().getSimpleName()));
        // execute the spring code to map ConstraintViolations to ObjectError
        super.processConstraintViolations(map(cve.getConstraintViolations()), 
                errors);
        return errors;
    }
}
// needed as we have to map between &lt;?&gt; and &lt;Object&gt;
static Set&lt;ConstraintViolation&lt;Object&gt;&gt; map(Set&lt;ConstraintViolation&lt;?&gt;&gt; input) {
    return input.stream().map(v -&gt; (ConstraintViolation&lt;Object&gt;)v).collect(Collectors.toSet());
}</pre></div>



<p>Having this bridge we can just call it to convert the <code>ConstraintViolationException</code><strong> </strong>to a proper Spring <code>BeanPropertyBindingResult</code>.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Adjusted Controller Advice&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@ControllerAdvice
public class HateoasJsrErrorExceptionMapper {
    private SpringValidatorBridge validatorBridge;
    
    @Autowired
    public HateoasJsrErrorExceptionMapper(Validator validator) {
        validatorBridge = new SpringValidatorBridge(validator);
    }
    
    @ExceptionHandler(TransactionSystemException.class)
    public ResponseEntity&lt;Object&gt; handleConstraintViolation(TransactionSystemException e, ServletWebRequest request) {
        ResponseEntity&lt;Object&gt; result;
        if (e.getRootCause() instanceof ConstraintViolationException) {
            ConstraintViolationException cve = (ConstraintViolationException)e.getRootCause();
            
            BeanPropertyBindingResult errors = validatorBridge.processConstraintViolations(cve);
            result = ResponseEntity.badRequest().body(ValidationError.builder()
                    .message(cve.getMessage())
                    .path(request.getRequest().getRequestURI())
                    .errors(errors.getAllErrors())
                    .build());
        } else {
            result = null; // not handled here
        }
        return result;
    }</pre></div>



<p>In the end, we can again pass the list of <code>ObjectError</code>s to our created <code>ValidationError</code> class, like in solution 1 and we receive the expected result from it.</p>



<h3 class="wp-block-heading">Which solution to use?</h3>



<p>Well to decide this depends on the personal taste. I personally like the 1.2 solution the most because it has the advantage to fail fast and is maybe somehow cleaner. But in then I end up doing the validation twice of course. Once on my event listener and once by hibernate.</p>



<p>Overall it depends on the personal taste and if it is anyway needed to catch and handle DB errors too. As so we need maybe both solutions.</p>



<h3 class="wp-block-heading">Links</h3>



<ul class="wp-block-list"><li><a rel="noreferrer noopener" aria-label="Git Repository (öffnet in neuem Tab)" href="https://github.com/sterlp/training/tree/master/hateoas-validation" target="_blank">Git repository to this blog</a></li><li><a href="https://docs.spring.io/spring-data/rest/docs/current/reference/html/#validation">https://docs.spring.io/spring-data/rest/docs/current/reference/html/#validation</a> </li><li> <a href="https://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/validation.html">https://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/validation.html</a> </li><li> <a href="https://jira.spring.io/si/jira.issueviews:issue-html/DATAREST-593/DATAREST-593.html">https://jira.spring.io/si/jira.issueviews:issue-html/DATAREST-593/DATAREST-593.html</a> </li><li><a href="https://stackoverflow.com/questions/45070642/springboot-doesnt-handle-javax-validation-constraintviolationexception">https://stackoverflow.com/questions/45070642/springboot-doesnt-handle-javax-validation-constraintviolationexception</a> </li></ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2020/02/spring-boot-hateoas-jsr303-validation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
