question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

cannot use `void` for Postgres functions which return `void`

See original GitHub issue

MyBatis version

3.5.7

Database vendor and version

PostgreSQL 11.6 (Debian 11.6-1.pgdg90+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit

Postgres JDBC driver: org.postgersql:postgresql:42.2.23

Test case or example project

@Select("SELECT pg_advisory_xact_lock(#{key})")
void lock(@Param("key") long key);

Steps to reproduce

Some of the Postgres advisory locks are functions that return void. The mapper code above breaks with the following error:

Caused by: org.apache.ibatis.executor.ExecutorException: No constructor found in void matching [java.lang.String]
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createByConstructorSignature(DefaultResultSetHandler.java:702)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:658)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:631)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:398)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:355)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:329)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:302)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:195)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:136)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
	... 37 common frames omitted

The mapper works if we change void to Void (from the “primitive” void, to the object Void). But in that case, it always returns a null, which is not useful.

Expected result

At the very least, Postgres functions (note: functions, not procedures - these things cannot be called with CALL functionName()) that return void should be mappable by MyBatis to the void (lowercase) “primitive” “type” in Java.

Ideally (much better), MyBatis should be able to map any result set to void, which would mean that we can safely ignore the entire result set.

Actual result

Cannot use void as a result for Postgres functions which return void.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
cvmocanucommented, Nov 8, 2021

I would rather not change the MyBatis code just for these unorthodox functions.

If the change is small, maybe it’s worth doing. If it requires a lot of work, you could just close this issue - I agree that the workarounds are good enough. Though, maybe it’s worth adding a few lines to document this, because the error is quite strange.

0reactions
cvmocanucommented, Nov 8, 2021

I would say that a function returning void looks weird. It is a procedure, isn’t it? thinking

Completely agreed. Unfortunately, that how the Postgres team designed stuff, and their JDBC driver works fine.

Thanks for the workarounds. I think the least weird for now is the one I had above: use java.lang.Void as the result type.

Read more comments on GitHub >

github_iconTop Results From Across the Web

plpgsql Error: RETURN cannot have a parameter in function ...
I get an Error: could not Retrieve the result : ERROR: RETURN cannot have a parameter in function returning void LINE 11: RETURN...
Read more >
8.3: Query Language (SQL) Functions - PostgreSQL
Unless the function is declared to return void, the last statement must be a SELECT. Any collection of commands in the SQL language...
Read more >
Thread: Can't use WITH in a PERFORM query in PL/pgSQL?
PostgreSQL 9.0. ... This has to be done even when the query doesn't have a= result (as when calling a function returning void)....
Read more >
Mockito Mock Void Method - DigitalOcean
But when we have to mock a void method, we can't use when() . ... operations when a mocked object method is called...
Read more >
2.3 — Void functions (non-value returning functions) - Learn C++
Do not put a return statement at the end of a non-value returning function. Void functions can't be used in expression that require...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found