Я предполагаю, что когда вы выполняете вызов для выполнения запроса, у вас есть оператор, и вы получаете исключение, поэтому в этот момент у вас есть оба. Кажется, вы могли бы провести там анализ.
Однако, может быть, вы догоняете вещи дальше. Итак, вы можете сделать на своем собственном подклассе Exception, DatabaseException, добавить триггерный член SQLStatement с помощью метода get и set, а затем в месте, где вы пытаетесь выполнить инструкцию, перехватить исходное Exception из PostgreSQL, создать новый DatabaseException, задайте для triggeringSQLStatement оператор, который вы только что выполнили, и вызовите initCause () для DatabaseException, чтобы установить исключение, полученное из PostgreSQL, как причину вашего исключения; затем сгенерируйте исключение DatabaseException и вызывающий код, который его перехватит, будет иметь объект, который распечатывает очень приличную трассировку стека того, что произошло, плюс обеспечивает доступ к оператору SQL, вызвавшему проблему. Для получения дополнительной информации об этом подходе вы, возможно, захотите изучить цепочку исключений Java. Даже если вы не используете все то, что я только что описал, я думаю, вам определенно следует использовать цепочку исключений Java.
Если в коде нет места, где у вас есть доступ как к SQL-выражению, вызвавшему проблему, так и к исключению, которое выдается, мне было бы очень любопытно узнать, почему и как это возможно. И я бы посоветовал вам переделать свой код, чтобы у вас было такое место.
Редактировать: Поскольку вы хотите первым делом увидеть оператор SQL в журнале, вы, вероятно, также можете переопределить метод toString () вашего DatabaseException (или другие соответствующие методы; я не уверен, что вызывается при распечатке исключения) для распечатки включенного оператора SQL, при условии, что вы включили его, как я описал выше.