Java Bug in Timestamp.from(Instant.MIN) – JDK-8068958

I just landed on this bug working with Java 11. There was a query returning an empty value, with the only discernible issue being related to date handling.

When the date was null, the code took a far-past date using the following code (not my code):

Timestamp.from(Instant.MIN) 

While one might expect this to return the epoch start date of 1970, it instead produced an unexpected far-future date: 169108098-07-04 06:51:43.0. This anomaly understandably caused confusion and hindered the ability to retrieve data from the database effectively.

It is a know but https://bugs.openjdk.org/browse/JDK-8068958 fixed in Java 23. There is a good explanation in this link.

The root cause of this issue lies within the Timestamp.from(Instant instant) method implementation. Despite expectations of an ArithmeticException being thrown in the event of arithmetic overflow during the conversion process, the exception never occurred as anticipated. Consequently, the method proceeded silently, resulting in incorrect timestamp values being generated.

public static Timestamp from(Instant instant) {
try {
Timestamp stamp = new Timestamp(instant.getEpochSecond() * MILLIS_PER_SECOND);
stamp.nanos = instant.getNano();
return stamp;
} catch (ArithmeticException ex) {
throw new IllegalArgumentException(ex);
}
}

Tip: Efficient Data Deletion Strategies in JPA for Large Datasets (beware of deleteAll in JPA)

Note for me: Please remember to use the search function to find this note in the blog when needed.

If you need to delete all data from a JPA table, avoid using the deleteAll method as it will iterate through all elements and delete them one by one. This can be time-consuming and inefficient, especially when dealing with a large amount of records. I

public void deleteAll() {
Iterator var1 = this.findAll().iterator();

while(var1.hasNext()) {
T element = var1.next();
this.delete(element);
}
}

Source: https://github.com/sbj156/-/blob/master/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java#L196

Instead, use the deleteAllInBatch method with the typical delete from statement.

@Transactional
public void deleteAllInBatch() {
this.em.createQuery(this.getDeleteAllQueryString()).executeUpdate();
}
private String getDeleteAllQueryString() {
return QueryUtils.getQueryString("delete from %s x", this.entityInformation.getEntityName());
}

Source: https://github.com/sbj156/-/blob/master/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java#L208

If that is not an option, consider using truncate to delete all data from the table.

 @Modifying
@Transactional
@Query(value = "TRUNCATE TABLE my_entity", nativeQuery = true)
void truncateTable();

DATABASECHANGELOGLOCK table (liquibase) and kubernetes

In Kubernetes and database management, handling the DATABASECHANGELOGLOCK table is crucial to ensure the smooth operation of your applications. The sudden reboot of application pods can lead to challenges related to locks within this table. In this article, we’ll explore two effective solutions to address this issue.

Option 1: Leveraging Init Containers

One approach to mitigate the challenges associated with DATABASECHANGELOGLOCK table locks is to use Kubernetes init containers. These init containers are designed to run before the main application container starts. Here’s how you can implement this solution:

Init Containers for Database Schema Updates: By utilizing init containers, you can execute database schema updates before your application container initializes. This ensures that your application operates with the latest schema version and helps prevent conflicts in the DATABASECHANGELOGLOCK table.

https://www.liquibase.com/blog/using-liquibase-in-kubernetes

Option 2: Liquibase Extension – Session Lock Support

Another effective approach to managing DATABASECHANGELOGLOCK table locks is by using a Liquibase extension called «Session Lock Support.» This extension is designed to release the lock when the database connection drops unexpectedly. Here’s how you can utilize this extension:

Session Lock Support Extension: By integrating the Liquibase Session Lock Support extension into your Liquibase configuration, you can automatically release locks when database connections are disrupted. This is particularly valuable in Kubernetes environments where pod reboots can occur.

https://github.com/blagerweij/liquibase-sessionlock

Choose the option that best aligns with your specific requirements and infrastructure to maintain a robust and reliable database schema management process.

Pequeño proyecto para convertir PDFs de Heytrade a Excel

He creado un pequeño proyecto para convertir los PDF del broker Heytrade a Excel y después usar sus datos más fácilmente para el control de las carteras.

El proyecto está hecho en un ratillo, por lo que no hay control de errores ni nada. Tan solo sirve a su propósito. Tiene un pequeño README para su uso.

Espero que sea de utilidad a los usuarios del HeyTrade.

Enlace a Github

Spring rest service doesn’t return the message of the exception

When we receive the response after calling a rest service, we wait for an error message to help get the problem’s origin. In this case, we got the correct code but the message was the one related to the status code: «server error». Where was our error message?

{
    "timestamp": "<TIMESTAMP>",
    "status": 500,
    "message": "server error",
    "path": "/"
}

We started to check the ResponseStatusExceptionResolver and if the problem was related to this class. In fact, we created a custom ResponseStatusExceptionResolver and put a test message in the response to be sure that we were sending the message:

response.sendError(500, "TEST MESSAGE");

Sadly, I received the same message: «server error». So we started to google for a solution and find that by putting in the properties file the property server.error.include-message=always, the Spring Boot will send our error message. But we had no luck. (https://stackoverflow.com/questions/62561211/spring-responsestatusexception-does-not-return-reason)

Then, we started to check the Javadoc of the following method HttpServletResponse#sendError(int,String):

«If an error-page declaration has been made for the web application corresponding to the status code passed in, it will be served back in preference to the suggested msg parameter and the msg parameter will be ignored

Maybe, the problem was related to the error page. The error message is right when it runs locally, it only fails if we activate the HTTP security in our remote servers.

We reached this question in Stackoverflow: https://stackoverflow.com/questions/70270993/error-response-body-is-empty-in-spring-boot-2-6 and got the following solution:

«If you permit access to the /error whitelabel page in your SecurityConfig it should work again. However, this seems to be a workaround as the issue is still in progress.»

The problem IS located in the security context of Spring. The error message is overwritten with the configuration in Spring Security so the message is lost and replaced with the standard error message of the status.

We have two solutions to resolve the problem: permitAll access to the error page or disable the errorPageSecurityInterceptor.

The issue for the first solution is ResponseStatusException no longer returning response body in 2.6.1 using spring security, but if you don’t want to allow access to the error pages, you should check this another issue Page with permitAll is no longer accessible via auto-configured MockMvc to disable an interceptor adding the following bean to your config:

@Bean
static BeanFactoryPostProcessor removeErrorSecurityFilter() {
    return (beanFactory) -> 
        ((DefaultListableBeanFactory)beanFactory).removeBeanDefinition("errorPageSecurityInterceptor");
}

This problem was reproduced in Spring Boot 2.7.1 with Spring Security. At different sites, developers complain about versions 2.5.7 or 2.6.x

Error en h2 v1.4.200 y acceso a LOB

Si usáis la base de datos H2 en su versión v.1.4.200 y tenéis tablas con campos LOB declarados, es posible que se esté produciendo el siguiente error cuando se intente acceder a ellos:

Caused by: java.lang.NullPointerException at org.h2.store.LobStorageMap.copyLob(LobStorageMap.java:255) at org.h2.value.ValueLobDb.copyToResult(ValueLobDb.java:554) at org.h2.value.ValueLobDb.copyToResult(ValueLobDb.java:40) at org.h2.result.LocalResultImpl.cloneLobs(LocalResultImpl.java:280) at org.h2.result.LocalResultImpl.addRow(LocalResultImpl.java:315) at org.h2.command.dml.Select.queryFlat(Select.java:744) at org.h2.command.dml.Select.queryWithoutCache(Select.java:884) at org.h2.command.dml.Query.queryWithoutCacheLazyCheck(Query.java:151) at org.h2.command.dml.Query.query(Query.java:435) at org.h2.command.dml.Query.query(Query.java:397) at org.h2.command.CommandContainer.query(CommandContainer.java:145) at org.h2.command.Command.executeQuery(Command.java:202)

Esto se debe al intentar acceder a un registro LOB mientras se realiza una ejecución en paralelo como pueden ser dos sesiones abiertas usando la misma tabla. Se resuelve bajando la versión de H2 a la 1.4.196.

Lo detectamos durante la ejecución de los tests y no parece que exista solución al mismo, ya que supondría rehacer toda esta parte de H2. El hilo completo del problema, origen del mismo y cómo reproducirlo se encuentra en:
https://github.com/h2database/h2database/issues/1808

Free ebooks and one course

Gradle:

Free training about Gradle:

O’Reilly books:

Comienzo de «Software Construction in Java»

Acaba de comenzar el curso Software Construction in Java en edX. No es un curso para aprender a programar en Java y sirve para refrescar algunos conceptos cuando quieres explicarlos a otras personas. Además, también usa un poco de Python.

Algunos recursos que he encontrado en el curso son:

Free eBooks

From  Sevilla Java User Group (SVQJUG):

Free eBook: Effective Performance Engineering

In order to deliver meaningful results, you need to build Effective Performance Engineering into every aspect of the enterprise, from IT and business management to internal and external customers and all other stakeholders. In this report, you will learn why success depends on adopting a cross-discipline, intra-business mindset that enables you to build a performance-focused culture throughout your organization.

http://www.oreilly.com/pub/cpc/25670

Free eBook: Release Engineering

With this excerpt from O’Reilly’s Site Reliability Engineering, you’ll learn how Google’s approach can inform your own company’s release engineering process—regardless of company size or the tools you use. Google Release Team member Dinah McNutt explains the rationale behind the company’s release engineering philosophy of self-sufficient teams, frequent (often-hourly) releases, and a self-contained build process that depends on known versions of build tools and dependencies.

http://www.oreilly.com/pub/cpc/25671