spring convention with jpa

my current project has jpa library in the classpath (for some class dependency only). As a result, spring boot will try to set up the jpa entitymanager etc, which are not really needed.

finally figured out the way to disable the convention is by configuring


serialization for enum

turns out when serialization for Enum, instead of customizing the serializer to customize the output, it’s possible to annotate the method or field with @JsonValue.

enum Mode{
Mode(String instance){
String instance;

this would then give out "AIRBUS" and "TESLA" instead of FLIGHT and ROAD.

@Lazy at injection point

Turns out when spring inject the bean with `@Lazy annotation, it's actually not delaying` the bean initialization, which is separately controlled at the @Bean or @Configuration level.

the injection point is instead creating a proxy object, with all attributes nulled, and for the methods, it will direct to the actual bean.

spring circular reference

while spring framework is discouraging use of filed injection, and in preference of constructor injection for example. There is an issue with circular reference.

For example:

class BeanA{
    public BeanA(BeanB beanB) {
        this.beanB= beanB;

class BeanB{
    public BeanB(BeanA beanA) {
        this.beanA= beanA;

Field injection would otherwise work. However, with above constructor injection, spring would throw out



The dependencies of some of the beans in the application context form a cycle:

|  beanA defined in URL [jar:file:/...class]
↑     ↓
|  beanB defined in URL [jar:file:/....class]
↑     ↓
|  xx (field xx) 

The alternative solution if must use constructor binding is to use lazy annotation

class BeanA{
    public BeanA(@Lazy BeanB beanB) {
        this.beanB= beanB;


increment and decrement operator

there is an interesting result for this operation

slotCount.computeIfPresent(indice, (k,v) -> v--);

it supposed to reduce the value by one for corresponding indice as the key.

however, the result is `the value is never changed`.

it’s a good reminder, as it happens, the incremental operator is conducting two operations. And the increment/decrement is after the first operation (return the value here) is done.

so the solution is

slotCount.computeIfPresent(indice, (k,v) -> v-1);//return -1 result

slotCount.computeIfPresent(indice, (k,v) -> --v);//minus one, then return

update symbolic link

the command to update the symbolic link is trivial,

ln -sf newPath link

`-f` basically force the overwrite if the link is already existing.

however, the caveat is if the link is pointing to a folder, `-n` is also needed, otherwise it will create a symbolic link to the newPath inside link.

ln -sfn newPath link

even further, even if -n is used, however, if there is `/` after the link (tab completion would do that), the newPath would still be symbolinked into link as a subfolder.

## this won't work
ln -sfn newPath link/  

java parallel stream splitter

Further to the issue with default JDK implementation with IteratorSpliterator, https://lwpro2.dev/2020/12/21/files-list-parallel-stream/

I have created a custom Spliterator to evenly split the stream and with threshold for the split size.

public class CacheSplitter<T> implements Spliterator<T> {
//    private final Collection<T> collection;
    private final T[] values;
    private int start;
    private int end;
    private final int THRESHOLD;
    public CacheSplitter(T[] values, int threshold) {
        this(values, 0, values.length, threshold);
    public CacheSplitter(T[] values, int start, int end, int threshold) {
        this.values = values;
        this.start = start;
        this.end = end;
        this.THRESHOLD = threshold;

    public boolean tryAdvance(Consumer action) {
        if(start< end){
            return true;
        return false;

    public Spliterator trySplit() {
        if(end - start < THRESHOLD){
            return null;
        int mid = (start + end)/2;
        return new CacheSplitter(values, start, start= mid+1, THRESHOLD);

    public long estimateSize() {
        return end - start;

    public int characteristics() {