Reputation: 21
I have the following function and table in my PostgreSQL database:
CREATE OR REPLACE FUNCTION generate_uid(size INT) RETURNS TEXT AS $$
DECLARE
characters TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
bytes BYTEA := gen_random_bytes(size);
l INT := length(characters);
i INT := 0;
output TEXT := '';
BEGIN
WHILE i < size LOOP
output := output || substr(characters, get_byte(bytes, i) % l + 1, 1);
i := i + 1;
END LOOP;
RETURN output;
END;
$$ LANGUAGE plpgsql VOLATILE;
create table users
(
userid text primary key default generate_uid(50)
, username varchar (50) not null
, pass varchar (50) not null
, firstname varchar (100) not null
, lastname varchar (100) not null
, email varchar (150) not null
, roleid int not null
, constraint fkrole foreign key(roleid) references userrole(roleid)
);
Then I call on the function in my DAO in JDBC with this block of code:
Account A = new Account();
String sha256hex = Hashing.sha256()
.hashString(password, StandardCharsets.UTF_8)
.toString();
try (Connection conn = CustomClassFactory.getConnection()) {
String sql = "INSERT INTO users (username, pass, firstname, lastname, email, roleid) VALUES (?,?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, userName);
ps.setString(2, sha256hex);
ps.setString(3, firstName);
ps.setString(4, lastName);
ps.setString(5, email);
ps.setInt(6, roleId);
System.out.println(ps.toString());
int i = ps.executeUpdate(); // <---update not query. this line is what sends the information to the DB
if (i == 0) {
System.out.println("Sorry, database was not updated. Returning to menu");
return null;
}
} catch (SQLException e) {
System.out.println("Sorry, database was not contacted. Bring your developer coffee. In the Insert Statement");
e.printStackTrace();
return null;
}
I am receiving the following error from the Stack Trace:
org.postgresql.util.PSQLException: ERROR: function gen_random_bytes(integer) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Where: PL/pgSQL function generate_uid(integer) line 8 during statement block local variable initialization
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2552)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2284)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164)
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:130)
at dao.AccountDaoImp.CreateAccount(AccountDaoImp.java:35)
at testing.Tester.main(Tester.java:11)
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "models.Account.toString()" because the return value of "dao.AccountDaoImp.CreateAccount(String, String, String, String, String, int)" is null
at testing.Tester.main(Tester.java:11)
How do I make sure it sees the function when I create a new user? The function is designed to generate a random string of text to use as a unique ID.
Upvotes: 0
Views: 491
Reputation: 321
gen_random_bytes
is part of the pgcrypto extension.
So run this in your database:
CREATE EXTENSION pgcrypto SCHEMA public;
To make sure you don't have to rely on search_path
, you can prefix public
to the function call, like in public.gen_random_uuid()
.
Upvotes: 2