-
Notifications
You must be signed in to change notification settings - Fork 851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQLWarnings returned on successful SQL statements #3300
Comments
org.hibernate.jdk.playground.MyTest Time elapsed: 0.111 s <<< ERROR! Surely you could provide a simpler example ? |
Surely I can, assuming you have postgres running on port 5432 with user Here's another branch:
|
And here's code if you'd rather use that: package org.hibernate.jdk.playground;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class MyTest {
@Test
void test() {
try (
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test", "test", "test");
Statement stmt = conn.createStatement();
) {
stmt.execute("DROP TABLE IF EXISTS tableThatDoesNotexist");
Assertions.assertNull(stmt.getWarnings());
} catch (SQLException e) {
Assertions.fail("SQLException caught", e);
}
}
} |
Agreed, we should not send these to the client. |
The driver is not in a position to judge useful vs useless messages. If the app does not want messages from the backend, one could consider adjusting client_min_messages |
In this case they are not SQLWarnings.
|
JDBC has only sqlwarning interface, so it looks fine we funnel all the messages via the only available api. |
Right, but it's not a warning, so I think we can safely ignore it. |
Ignoring the messages would break backward compatibility |
Yes, I'm concerned what we might break. |
I don't see how this could possibly break any sensible code. Currently the driver is sending us a But worse, the driver is warning me that something happened which I explicitly stated can happen, and should be ignored in the text of the SQL statement being executed. So this warning is completely useless to the client in a very strict sense. The client knows that the table might not have existed, having stated that explicitly up front. And after execution of the statement, the end result is that the statement was successful either way: the table is now inexistent, whether it previously existed or not. What possible use could that I realize that you probably don't get many complaints about this behavior. Why? Well, because typical JDBC code simply ignores |
Please suggest how the driver should return messages emitted by the backend. |
Please ask PostgreSQL developers so they remove the message in the first place. If you are sure the message is completely useless, sure you could convince the backend devs about it |
Well I guess the SQL State tells the story: Warnings should be reported if the code starts with No? |
Would you please clarify the corresponding JDBC specification that says that? -- The server reports a notice message along with the corresponding SQLState, position, severity and so on. There might be applications that use |
Yes, I understand the issue.
See Vladimir's example of a trigger that just reports NOTICE's
Which is why assuming applications are sane is a challenge. I think the simplest solution to solve this is for Hibernate to issue |
I mean, sadly the JDBC spec and javadoc are completely silent on the question of which conditions should result in a From the PostgreSQL documentation here: https://www.postgresql.org/docs/current/errcodes-appendix.html and here: https://www.postgresql.org/docs/current/ecpg-errors.html it's clear that SQLSTATE 00000 is not a warning. On the contrary, it's described as "Successful Completion" and as "Indicates no error". On the other hand:
(Note that there is no such parenthesized phrase in the description of class 00.) Even more clearly, if I run
That's But look, just relying on common sense. If I send |
A NOTICE is not a WARNING, by definition. And so it appears wrong to represent it as a
Hibernate doesn't in general have control over configuration of the JDBC connection. That's usually handled by other framework/server code. |
@gavinking , would you please ask PostgreSQL developers so they remove the notice message or reduce its severity to DEBUG or something like that?
Please provide a link to JDBC specification that says If JDBC spec had something like Here's a use case: imagine multiple application threads drop a table, and they want to perform a cleanup. The application might implement the following:
It would implement "single cleanup" semantics even in case multiple concurrent threads attempt dropping the table (e.g. a historical partition) |
I'm not debating
I haven't looked in a while, but you do have a PostgreSQL dialect. Sending an SQL set at the beginning doesn't seem out of place to me ? |
I mean that's the thing. The message isn't completely useless when I'm working in So the problem is not with the backend. The thing that's wrong is that the JDBC driver is reporting a NOTICE as a
Yeah, sure, OK, I understand your point that JDBC doesn't give you a way to report NOTICEs. But then reporting them as warnings by default also doesn't seem right. [If this was something you could opt into, that would be completely fine, but it's the default behavior.] I mean, let's take a step back: JDBC doesn't give you a way to report LOG or DEBUG1 messages either. But I definitely wouldn't want you to send these back as Well, actually, wait up, what does happen in this case? If I set
Oh apologies, I read too fast, and I thought you meant it was a JDBC connection property. Indeed, we could easily run a [It doesn't really solve the problem that NOTICEs are being reported as warnings, of course.] |
Well not everyone is using JDBC for CRUD apps. People do write monitoring and psql like apps in JDBC. https://www.jackdb.com/ for instance.
No we don't again the spec doesn't have a SQLDebug message or the like.
Agreed |
You don't filter them out, or you don't send them to the client? |
We don't filter them out. |
OK, so that really doesn't seem like the right default behavior.
Yeah, I mean, like, I think it's fine that people who're doing something other than OLTP have an opt-in feature to gain access to this stuff. (As a JDBC parameter or whatever.) I just don't think it's the right default. |
Ironically this whole thing is caused because PostgreSQL ships with
Users would have to change
As noted above had Postgres chosen to ship with client_min_messages=WARNING this would be a non-issue. Again we try to be as agnostic as possible. |
An update: @gavinking followed your recommendation to use So regardless of what you decide on this topic, Hibernate ORM users should be fine. Thank you for the discussion! |
You're welcome |
Describe the issue
For some SQL statements (e.g.
DROP TABLE IF EXISTS ...
), after they execute successfullypgjdbc
attachesSQLWarning
objects to the statement/connection.These warnings have an SQLState starting with
00
, which makes them technically "success" messages, not "warnings".This leads to Hibernate ORM faithfully logging these warnings-but-not-quite, which is considered too noisy by some: quarkusio/quarkus#16204 , https://hibernate.atlassian.net/browse/HHH-18296
Driver Version?
42.7.3
Java Version?
11 or 17 or 21
OS Version?
Fedora 40
PostgreSQL Version?
16 in my test, but doesn't seem to matter.
To Reproduce
Steps to reproduce the behaviour:
Expected behaviour
I would expect no
SQLWarning
when an SQL statement executes succesfully, since the database didn't return any warnings (only success messages).Instead, a
SQLWarning
is generated.Logs
N/A
The text was updated successfully, but these errors were encountered: