import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Properties;

import org.postgresql.Driver;
import org.postgresql.util.DriverInfo;

public class BindUUID {

	private static final String JDBC_URL = "<your url>";
	private static final Properties credentials = new Properties();
	private static final String SQL = "select * from test_table where ? is null or ? = c_uuid";

	static {
		credentials.setProperty("user", "<user>");
		credentials.setProperty("password", "<password>");
	}

	public static void main(String[] args) throws ClassNotFoundException, SQLException {

		Class.forName("org.postgresql.Driver");

		System.out.println("JDBC Driver Version: " + DriverInfo.DRIVER_VERSION);

		try (Connection connection = DriverManager.getConnection(JDBC_URL, credentials)) {

			// Create test table
			try (Statement statement = connection.createStatement()) {
				try (ResultSet rs = statement.executeQuery("select version()")) {
					rs.next();
					System.out.println("PostgreSQL version: " + rs.getString(1));
				}
				statement.execute("create table test_table (c_uuid uuid)");
			}

			// works but is not satisfying (hack)
			try (PreparedStatement statement = connection.prepareStatement(SQL)) {
				statement.setNull(1, Types.VARCHAR);
				statement.setObject(2, null);
				System.out.print("setNull(varchar) + setObject(null) => ");
				statement.execute();
				System.out.println("works");
			} catch (Exception e) {
				System.out.println("fails (" + e.getMessage() + ")");
			}

			// does not work, expected (untyped null)
			try (PreparedStatement statement = connection.prepareStatement(SQL)) {
				statement.setNull(1, Types.OTHER);
				statement.setNull(2, Types.OTHER);
				System.out.print("setNull(other) + setNull(other) => ");
				statement.execute();
				System.out.println("works");
			} catch (Exception e) {
				System.out.println("fails (" + e.getMessage() + ")");
			}

			// does not work, but should
			try (PreparedStatement statement = connection.prepareStatement(SQL)) {
				statement.setNull(1, Types.OTHER, "uuid");
				statement.setNull(2, Types.OTHER, "uuid");
				System.out.print("setNull(other, uuid) + setNull(other, uuid) => ");
				statement.execute();
				System.out.println("works");
			} catch (Exception e) {
				System.out.println("fails (" + e.getMessage() + ")");
			}

			// Drop test table
			try (Statement statement = connection.createStatement()) {
				statement.execute("drop table test_table");
			}
		}
	}
}