duplicate key violates unique constraint when using multi-threading
By creating a unique constraint on your table, you are telling the database "each time I try to insert a row in this table, please check that there is no existing row with this combination of columns the same. Oh, and make sure you do it in an atomic fashion so that if someone else tries to insert one at the same time as me, only one of us will succeed".

After doing that, in most cases there is little point in replicating the same logic in your application. It will only make the process less efficient. You would be better off to take @horse's suggestion and catch the exception.

There are a couple of things to watch out for though. One is that if you doing this inside a transaction, then the transaction will be automatically rolled back on the error. If you did anything else prior to this in the transaction, it will have been undone. To avoid this, you need to set a SAVEPOINT prior to the insert, and then RELEASE or ROLLBACK the savepoint as appropriate.

The other issue is that the postgresql log will still contain these errors, even if they are caught and ignored by the Java code. Flooding your logs with meaningless noise helps to hide true problems that might be lurking in there, so it is not a good thing.

Possibly a better solution, which avoids both of these problems, is to create a stored procedure which inserts the record, handles any exceptions which occur, and returns an indication to your application as to whether the record was stored or not.

For example, if you had a table that looked like this:

CREATE TABLE test(a INTEGER, b TEXT, UNIQUE(A,B));


Then you could have a function like this:

CREATE FUNCTION test_insert(pa INTEGER, pb TEXT) RETURNS INTEGER AS $$
BEGIN
    INSERT INTO test(a,b) VALUES (pa, pb);
    RETURN 1;
EXCEPTION
    WHEN unique_violation THEN
       RETURN -1;
END;
$$ LANGUAGE plpgsql;


and you could use it like this:

testdb=&gt; SELECT test_insert(1,'foo');
 test_insert
-------------
           1
(1 row)

testdb=&gt; SELECT test_insert(1,'foo');
 test_insert
-------------
          -1
(1 row)


If an attempt is made to insert a record that violates the constraint, no exception is thrown or logged, and if executed inside a transaction, the transaction is not affected. The function returns a value which you can use to see if the record was inserted or not. It is a very basic example, but should illustrate the point.