Archive for the 'Spring Boot' Category

October 5th, 2022
4:16 pm
Using Spring Data JPA with Oracle

Posted under CouchDB & Java & JPA & Knowledge Base & Oracle & Spring & Spring Boot & Spring Data JPA
Tags , ,

I was using Spring Data JPA with Oracle as part of an export process from CouchDB to Oracle. The CouchDB export application first exports my existing Places data from CouchDB, then maps it to the entity model I am using for JPA/Oracle, then persists it into Oracle, and finally performs some rudimentary listing of the Oracle data by logging it.

Some issues/points came to light during this excercise which I am noting here:-

1/ My connect string to Oracle was using a Pluggable database in Oracle XE. This needs to use a service name (xepdb1) rather than a SID (xe) for the connection. To do this I needed to use a slash before the service name in the application properties, to indicate a service name, rather than the colon I would normally use for a SID:

# Oracle settings
spring.datasource.url = jdbc:oracle:thin:@localhost:1521/xepdb1
spring.datasource.username = places
spring.datasource.password = xxxxxxxx

2/ I changed the Hibernate naming strategy in the application properties to prevent unwanted snake casing of Oracle column names:

# Hibernate settings
spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

3/ For persisting to Oracle, I had the choice of using Spring Data JPA, calling save() or saveAll() on the Individual Repository interfaces that extended CrudRepository (such as PlacesRepository), or I could use the Entity Manager. The Spring Data methods would persist or update fine, and could also save an iterable in one call. However, I had some small additional logic as I was passing and returning a Map. As I chose not to put this logic in the service layer, I therefore used an ordinary JPA Dao (repository) class, and autowired the entity manager via the @PersistenceContext annotation. I could therefore incorporate my logic in a single call and use entityManager.merge() to persist. I felt that situations vary and that it was not always appropriate to use Spring Data Interfaces for some use cases. However the Spring Data find queries were useful and clever for querying the database as they allowed for example a find by key with a like, and order by, just by declaring the appropriate method calls in the interface. I also used the @Query annotation for a custom query, which again was just annotated on a method in the interface.

4/ I had issues whereby the foreign keys on dependant entities were not being auto populated and threw up as null, even when I set nullable=false on the @JoinColumn annotations. In the end it was a simple case of not populating the objects in my model on both sides of the join before persisting – i.e. I was populating a list in a parent object for a one-to-many, but not populating the parent in the dependant object. Doing this resolved the problem and everything persisted automatically with a single parent persist/merge, with hibernate allocating primary keys via Oracle sequences, and then auto populating them in the foreign keys. This stack overflow post here pointed me in the right direction on this. I kept the nullable=false annotations where appropriate to correctly match the relationship I was using, and what was in Oracle.

5/ Once I was at the point of listing everything I had persisted, using Spring Data queries and some simple logging, I was initially hit with Hibernate multiple bag fetch exceptions when listing the data. At this stage I had annotated my repository methods as @Transactional rather than the service layer, and was therefore using explicit eager loading annotations as I needed everything to load before the methods returned. This post here details the issue, and it appears that Hibernate can only eagerly load one collection at a time. My solution to this was to take the more normal route of annotating my service methods as @Transactional rather than the repository, which then allowed a number of repository calls to be made from a single service method, all in the same transaction. Whilst this did expose the service layer to the transaction architecture and javax.transaction package, it is the more normal approach and gives flexibility in the service layer. In my case I could then just revert to the default lazy loading and perform the logging in the same service layer method (which I was happy to do as this was a very basic example just to demonstrate fetching the imported data from Oracle). Everything then worked fine.

 

Comments Off on Using Spring Data JPA with Oracle

May 9th, 2022
5:32 pm
Issues upgrading my Yoti Java IdentityAPI to JDK 17

Posted under Eclipse & Java & Knowledge Base & Spring & Spring Boot
Tags

I decided to go from Java 8 to the most recent LTS release of Java, JDK 17, and to the current latest Spring Boot, 2.6.7, for my Spring Boot Identity API which is a java back end interface to Yoti.

Initially I used Oracle JDK 17, and I hit an issue when running live with Yoti, but using the Java IdentityAPI locally. Curiously (and annoyingly) everything worked fine when running in debug under the latest eclipse, 2022-03, but I failed to get a Yoti profile back when running the compiled Spring Boot version directly.

This Spring Boot issue details the problem, which is exactly what I was getting – an error returned when getting the Yoti profile, due to an interaction between Spring Boot, Oracle jdk 17, and Bouncy Castle encryption, causing an IllegalStateException citing ‘zip file closed’ when the jar is being unpacked. The issue does not occur when running an exploded deployment (i.e. not in a fat jar), such as is done when running in debug in eclipse as I was.

There is no resolution at present, but as the problem does not occur under openJDK, I elected to switch to openJDK 17 rather than revert to Oracle JDK 11, which would have been another option.

Switching to openJDK 17 fixed the problem, and I was able to successfully perform age verification using a local Spring Boot IdentityAPI of mine, built with openJDK 17, and using the production Yoti to retrieve a live profile.

Whilst doing this, I improved the logging and elected to use Lombok’s @slf4j annotation to create loggers, for convenience, as this also allows logging to be tweaked via the Spring Boot application.properties as normal for Spring Boot. This is detailed here for reference.

In addition I upgraded the Yoti Java SDK I was using to the latest one (yoti-sdk-api version 3.4.0) rather than the old one I was using (yoti-sdk-impl version 2.6.0). This involved a small change to my YotiService as the interface to Yoti has changed, and some small pom changes for the new version. This all worked fine.

Comments Off on Issues upgrading my Yoti Java IdentityAPI to JDK 17

March 11th, 2020
12:43 pm
Using self signed SSL with Spring Boot

Posted under Java & Spring & Spring Boot & Web

I needed to use ssl for a Spring Boot backend web service for Yoti, as https is a Yoti requirement.

This post here details how to do this for Spring Boot. The official Oracle docs can also be found here.

The following configuration fragment from the Spring Boot application.properties shows how to configure for ssl using the created keystore (keystore.p12), which was placed in the deployment directory alongside the spring boot jar:-

server.port=8443
server.ssl.key-store-type=PKCS12
server.ssl.key-store=salientsoft.p12
server.ssl.key-store-password=<password>
server.ssl.key-alias=salientsoftdev

Comments Off on Using self signed SSL with Spring Boot

January 24th, 2020
5:32 pm
Spring Boot no longer returns HTTP reason phrase in responses

Posted under Java & Spring & Spring Boot & Tomcat

I noticed this when a web service returned a blank reason phrase, which tripped up Angular due to an Angular issue which I have documented here.

It appears to be a Spring Boot Tomcat version change issue – a later Tomcat ignores the reason phrase and does not return it, as detailed here.

As reason phrases are being deprecated anyway, and I don’t use them, I have just ignored the issue, but it is worth being aware of it when debugging.

Comments Off on Spring Boot no longer returns HTTP reason phrase in responses

December 8th, 2019
5:17 pm
Spring Boot not adding CORS headers in response when using WebMvcConfigurer

Posted under Spring & Spring Boot
Tags ,

I was using this to add CORS headers dynamically based on application.properties.

However initially Spring stubbornly refused to add the headers.

My initial (incorrect) code was as follows:-

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
 
    @Autowired
    private ConfigProperties config;
   
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        config.getCorsOriginsAllowed().forEach(origin -> registry.addMapping(origin).allowedOrigins(origin));
    }
}

The error was that I had used origin both as the registry mapping key and the resulting allowed origin.

The correct code should have used a URL path as the mapping key. The correct replacement line was as follows:-

        config.getCorsOriginsAllowed().forEach(origin -> registry.addMapping("/**").allowedOrigins(origin));

This fixed version mapped every URL path to the given set of origins, using “/**” as above.

This fixed the problem.

This post here by Baeldung and this Spring guide post detail the various ways to add CORS headers, both in a fixed static way using annotations, and in dynamic ways such as the above.

Comments Off on Spring Boot not adding CORS headers in response when using WebMvcConfigurer

December 8th, 2019
5:03 pm
Spring Tools Suite shows inconsistent warnings re applications.properties entries.

Posted under Spring & Spring Boot
Tags ,

STS tries to warn you when editing application.properties, if any properties do not match your configuration classes.

Unfortunately it sometimes gets out of step and does not give correct warnings.

I had a few intermittent instances of this which were cleared by refreshing/rebuilding/reloading.

However one persistent one was that whilst Spring Boot was happy with the map[key] syntax for specifying a property for a map entry, the IDE continued to give a warning on this.

In the end I could not resolve this, but using the map.key syntax instead was fine and the IDE was happy with this and did not give warnings.

The only real need for the [] syntax would be to support keys with special characters in like “.”, but in my case this was not an issue and I would normally avoid this anyway if at all possible.

Comments Off on Spring Tools Suite shows inconsistent warnings re applications.properties entries.

December 8th, 2019
4:52 pm
Spring Boot @Configuration class ignoring some application.properties entries

Posted under Spring & Spring Boot
Tags ,

I was using @Configuration on a configuration class in order to load its properties from application.properties.

This is detailed in this post here.

As per the post, Spring Boot supports lists and maps in the way you would expect, and handles nested objects including Collections such as maps and lists.

It can therefore handle a complete object graph of configuration properties in a clean manner, and also happily supports generics too.

Map keys can be specified either using the “.key” syntax, or the bracketed [key] syntax (which is also used with numeric values to create lists).

The problem I hit was that a map property group, used to create mock response objects keyed on a token string, was being completely ignored even though correctly specified in application.properties.

There were no errors or messages about this the log, even when debug logging was turned on – Spring appeared to be just ignoring the properties completely.

After some significant head banging the problem was trivial.

I was using Lombok to eliminate boiler plate, and both the map class and its descendants  had Lombok @AllArgsContructors and static factory methods for my own object creation.

However this meant that they did not have a no args constructor as I had not specified one. I did not need one, but Spring Boot absolutely relies on this to work!

Once I created the required constructor via @NoArgsConstructor, everything worked fine.

Hats off to Spring for this excellent way to manage config as a nice object graph, but it would be useful to have some kind of warning when a target class does not have a no args constructor!

Comments Off on Spring Boot @Configuration class ignoring some application.properties entries