Responsibility for loading data from the database environment

I have a question, I would like to know about the values ​​of the Major version of the database, the minor version, the name, all this data, who is in charge of loading them? Hikari, the corresponding driver of the DB or myself?
I was doing a debugging of this section, and I could only observe that they got most of the values ​​from System.properties(), and several others that were loaded from the beginning with respect to the properties established in my application.

I would like to know if you know who is in charge of loading those values ​​under the keys that you reference to get that data, because in my case they are not loaded at any time through these means, and the driver that I use does load them but through a common Java interface, I appreciate any help.

This is the package: org.hibernate.engine.jdbc.env.internal

Sorry, but I have no idea what you’re asking. Can you please rephrase the question?

What do you need these values for? Do you have a particular problem that you could explain about?

I was intrigued because when the data related to the DB was displayed, everything appeared unknown, but after investigating further I saw that the data that is loaded from the metadata, is loaded correctly, but it is not provided to be used by the log that is displayed, and by default it has the value “undefined/unknown”, but it does not affect any functionality, it is just a purely informative log.




{211780B0-97F9-4A7B-8DAD-692AA7EAFDB4}
{7EFD21F4-5AA0-4CDD-97F8-CC1E4B9917C8}
{9F91F4AB-34E3-435E-BEF2-E2D108046531}

I’m using Hibernate Core 6.6.2, and well, I was just doing some research out of curiosity,you can mark this as solved

I was intrigued because when the data related to the DB was displayed, everything appeared unknown

We have been informed about this “problem” before, but nobody provided a reproducer for this yet or cared to explain enough what is going wrong.

We’d very much appreciate if you could provide some details.

Well, this is my first time doing this, I’ve only been programming for a few months, so I’ll explain the workflow where the “error” occurs.

Everything starts in the class “public class JdbcEnvironmentInitiator implements StandardServiceInitiator” of the package:
“org.hibernate.engine.jdbc.env.internal”

in the method:
@Override
public JdbcEnvironment initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry)

Here a lot of information is loaded from the “environment” (hence my question in what context do you get the data from the database from the environment, because I understand that it is provided by the driver, and cannot come from the configuration values, which is a HashMap that brings information from the environment and some Hibernate configurations)

Then we move on to the section of loading the jdbcenviroment by 3 possible means: with accessible metadata, with explicit configurations and the default values.

My situation is metadata, because my drive with my database provides it and it is accessible

The getJdbcEnvironmentUsingJdbcMetadata method does several things, it builds the connection, the service, a temporary session, and then starts an executor that activates Hikari to get the connections to the DB.

In the following image you can see that it loads all the metadata provided by the connection to create a “dialectResolutionInfo”

Then a new JdbcEnvironmentImpl object is created using the above data, I won’t go into details, just that this object builds the Dialect, and because IBM is not among the standards, the construction of the dialect is somewhat abstract, and the construction of the JdbcEnvironmentImpl object only matters that it has metadata and dialect.

Now returning to the main code segment is where the problem occurs, the record is provided which in this case does not have the DB data, and the dialect is provided, which does not have all the DB data that the record requests, it only has the databaseversion object, metadata has jdbcurl, jdbcdriver, and connection which is not being returned by JdbcEnvironmentImpl has the value of whether autocommit is enabled and the default isolation level, the datasource which is located within the configurationvalues ​​hashmap under the key “hibernate.connection.datasource” has the pool sizes (although there is only the max one)

{9B926CF1-8E9A-4ED4-B77D-13B3DC7B1D31}

Here a validation is done using the registry to check the case it is in (both lead to the same final constructor), and the function is called and the dialect is provided, I will show when the first if is fulfilled

Call this function of type default in the interface “public interface ConnectionProvider extends Service, Wrapped” found in the package: “org.hibernate.engine.jdbc.connections.spi” and build a new object DatabaseConnectionInfoImpl

{F21144ED-9604-4FEE-B08E-30F443D9556A}

Now we have reached the class: “public class DatabaseConnectionInfoImpl implements DatabaseConnectionInfo” in package: “org.hibernate.engine.jdbc.connections.internal”

Here you can see that all values ​​are loaded with null except the database version, this calls another constructor within the same class which loads these values ​​as they are

{8F5E3314-B21C-4842-A872-322CA36010AB}

After returning the object completely, it reaches this line and its method is called to create the String that will be loaded into the Log

{489F1E31-DCF0-448B-B588-F17C79720E8A}

In this method, if it detects that the object is empty, it loads the default value that is in the same class that looks like this → public static final String DEFAULT = “undefined/unknown”

resulting in the Log that does not show the complete data

What occurs to me is that in the process of creating the dialectResolutioninfo, and jdbcenvironmentimpl, since in this part the metadata and connection are obtained, in the configuration values ​​the keys and values ​​corresponding to the url, driver, autocommit, Insulationlevel and the poolsize (that the datasource is within the hashmap at that moment), then 2 values ​​could be returned, the new JdbcEnvironmentImpl and the Configurationvalue (I don’t know if by reference the Configurationvalue is updated in the context of the main method, if so, it is not necessary to return it)

and that this method is able to receive the configuration values ​​as settings

{204984F7-DF2F-427A-8EA3-C3EC30019740}

The getDatabaseConnectionInfo of both objects also requires receiving the hashmap as settings

and instead of calling the constructor that only receives dialect, call the other one

{88767DB6-0FB7-411F-8E15-591BC80C750E}

This

and there they check the functions, what the keys that this already implemented code receives are called, and that would load the information correctly and return the object, and when obtaining its String version everything would be displayed correctly.

I don’t know if I’m not taking something into account, but with the code I saw, and in the use case where information is loaded through the metadata that could not be obtained previously by the configurationvalues ​​that reach this function, in that case to avoid this you can use computeIfAbsent to add the values. I hope my answer is useful.

What ConnectionProvider implementation is being used? You mentioned that you use a datasource, is it possible that you’re using the DatasourceConnectionProviderImpl?

yes, that same one

I just realized that this provider does call the full constructor, but it still has the same problem as the one that is set by default.

AFAICT, this is expected. Obviously, we can’t extract any of this information from a datasource.

Yes, so the pool size would be the problem, the rest can be extracted from, for example, metadata and connection, or from other places that I am not aware of, should I publish this information in Jira or leave it here?

You can certainly create an improvement request in Jira for using Connection Metadata to determine some of these values.