Sunday, December 18, 2016

Upgrading DB schema in Spring Boot projects

In this article we saw how to upgrade the DB schema in Spring Boot projects using the spring.jpa properties:
  • spring.jpa.generate-ddl
  • spring.jpa.hibernate.ddl-auto
There is, however, a far more powerful way to do the same upgrade. That is by using Liquibase.
  • Add org.liquibase:liquibase-core to your classpath.
  • Create a new changelog file (json):
 {
  "databaseChangeLog": [
    {
      "changeSet": {
        "id": "1",
        "author": "AUTHOR_NAME",
        "changes": [
          {
            "addColumn": {
              "columns": [
                {
                  "column": {
                    "name": "EMAIL",
                    "type": "VARCHAR(255)",
                    "defaultValue": email@email.com,
                    "constraints": {
                      "nullable": false
                    }
                  }
                }
              ],
              "schemaName": "MY_SHEMA_NAME",
              "tableName": "MY_TABLE_NAME"
            }
          }
        ]
      }
    }
  ]
}

  • Run liquibase update (this will run automatically when you start your Spring Boot project (make sure you set the changelog's path correctly in application.properties (liquibase.change-log=classpath:db/changelog/db.changelog-master.json))
That was all. Schema upgraded. You may wish to run updateSQL first, to output the upgrade SQL in a file so that it can be inspected before applying it in the database.

Read more in the official Liquibase site.

Tuesday, October 18, 2016

Thymeleaf dropdown with selected option

Thymeleaf suggests dropdown creation as follows:

<select th:field="*{type}">
<option th:each="type : ${allTypes}"
             th:value="${type}"
             th:text="#{${'seedstarter.type.' + type}}">Wireframe
</option>
</select>

However, if you want to have a 'selected' option this would not work:

<select th:field="*{type}">
 <option th:each="type : ${allTypes}"
              th:value="${type}"
              th:text="#{${'seedstarter.type.' + type}}"
              th:selected="${myCondition}">Wireframe
</option>
</select>

Instead you should do:

<select name="type">
<option th:each="type : ${allTypes}"
             th:value="${type}"
             th:text="#{${'seedstarter.type.' + type}}"
             th:selected="${myCondition}">Wireframe
</option>
</select>

Monday, September 12, 2016

Sending custom cookies with Postman

To send a custom cookie with Postman (API testing tool), set a "Cookie" header with value similar to "name=value". For example, to send JSESSIONID='Babis' include this header:

Header Key | Header Value
Cookie | JSESSIONID='Babis'

 As described here, you should first install Postman's interceptor extension.

Wednesday, September 7, 2016

Adding a new non-null column in a JPA entity with default value (on schema upgrade)

Say you have the following table:

Id | First | Last | Phone
1 Thoring Oakenshield 123456
2 Bilbo Baggins 654321

...and you want to add an extra Email column which should be non-null and default to email@email.com (without losing any data).

In you JPA entity, write:

@Column(nullable = false, columnDefinition = "Varchar(255) default 'email@email.com'")
private String email;
// getter + setter

Make sure you have these external properties set in application.properties:
  • spring.jpa.generate-ddl
  • spring.jpa.hibernate.ddl-auto

Read here for more details.

Also, keep in mind that this is not safe. Not to be used in production. Related stackoverflow discussion.

Tested this with
spring-boot-starter-data-jpa:1.3.1 and Oracle Database 11g Express Edition Release 11.2.0.2.0.

Thursday, August 25, 2016

Sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix


If you have an array of Strings, say ["9", "30", "0"], and you wish to convert it to a String "[9, 30, 0]", do:

StringJoiner sj = new StringJoiner(",", "[", "]");
Arrays.asList(myArray).forEach(p -> sj.add(p));
sj.toString();

More about StringJoiner:
https://docs.oracle.com/javase/8/docs/api/java/util/StringJoiner.html