4

I have created a class in Spring boot to establish a global javers object that can be used by all classes. This is my code.

@Component
public class JaversInstance {

    public static final Javers javers;
    static
    {

        ConnectionProvider connectionProvider = new ConnectionProvider() {
            @Override
            public Connection getConnection() throws SQLException {
                String url = "any_url";
                Properties props = new Properties();
                props.setProperty("user", "test");
                props.setProperty("password", "test");
                DriverManager.getConnection(url, props);
                System.out.println("CONNECTION PROVIDER invoked");
                return DriverManager.getConnection(url, props);
            }
        };

        JaversSqlRepository sqlRepository = SqlRepositoryBuilder
                .sqlRepository()
                .withConnectionProvider(connectionProvider)
                .withDialect(DialectName.MYSQL).build();
        System.out.println("JAVERS instance creation");
        javers = JaversBuilder.javers().registerJaversRepository(sqlRepository).build();
    }

    private JaversInstance() {

    }

}

Output:

JAVERS instance creation
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked

Can someone tell me what has happened here. Why the getConnection() is called so many times? Is this any kind of retry?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
a_good_human
  • 544
  • 3
  • 12

2 Answers2

1

Although the ConnectionProvider is instantiated inside a static block, its overridden method is neither static (can't be) nor related to the static block itself but to the instance connectionProvider.

Basically, you implement a method of an anonymous class. I suppose the ConnectionProvider is an interface, then defining a class implementing the very same interface would be effectively the same as your code:

static
{
    ConnectionProvider connectionProvider = new MyConnectionProvider();
}

The internals of the getConnection method is not bound to the static block, the instance connectionProvider itself is. There are multiple calls since the method has been invoked multiple times from an instance defined within the static block.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
1

It happens as many times as the anonymous class of ConnectionProvider is loaded. The following code will help you understand it better:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {
    static Comparator<Integer> comparator;
    static {
        comparator = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                System.out.println("Hello");
                return 0;
            }
        };
    }

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(40);
        list.add(20);
        list.add(10);
        list.add(30);
        Collections.sort(list, comparator);
    }
}

Output:

Hello
Hello
Hello
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • I could get this. But in my code, I have called the connectionProvider only once when initializing JaversSqlRepository. Then how is it called multiple times. Can you please explain in that context. – a_good_human Apr 21 '20 at 04:36